Exposed some adaptivity functions for use in cpsd
[charm.git] / src / libs / ck-libs / ParFUM / ParFUM_Adapt.h
1
2 /* This module contains the class which presents the 
3  * edge_bisect, edge_contract, edge_flip functions.
4  *
5  * File: ParFUM_Adapt.h
6  * Authors: Terry Wilmarth, Nilesh Choudhury
7  */
8
9 #ifndef __ParFUM_Adapt_H
10 #define __ParFUM_Adapt_H
11
12 class femMeshModify;
13
14 ///Provides primitive mesh modification functions
15 /** An adaptivity class which provides the primitive incremental mesh modification operations.
16  * These operations are edge_bisect, edge_flip and edge_contract.
17  */
18 class FEM_Adapt {
19  protected:
20   ///cross-pointer to theMesh object on this chunk
21   FEM_Mesh *theMesh;
22   ///cross-pointer to the femMeshModify object on this chunk
23   femMeshModify *theMod;
24   // Helper methods: see bottom of this file
25   /// Check if e1 and e3 are on the same side of edge path (n1, n, n2)
26   int check_orientation(int e1, int e3, int n, int n1, int n2);
27
28  public:
29   ///default constructor
30   FEM_Adapt() {
31     theMesh = NULL; theMod = NULL;
32   }
33   /// Initialize FEM_Adapt with a chunk of the mesh
34   FEM_Adapt(FEM_Mesh *m, femMeshModify *fm) { 
35     theMesh = m; theMod = fm; 
36   }
37   /// Initialize FEM_Adapt with the femMeshModify object
38   FEM_Adapt(femMeshModify *fm) { theMesh = NULL; theMod = fm; }
39   /// Initialize FEM_Adapt with the FEM_Mesh object
40   void FEM_AdaptSetMesh(FEM_Mesh *m) {theMesh = m;}
41   /// pup for this object 
42   void pup(PUP::er &p) {
43   }
44
45   /// Map a pair of element-local node numberings to an element-local edge numbering
46   int get_edge_index(int local_node1, int local_node2);
47   /// Find an element-local node numbering for a chunk-local node
48   int find_local_node_index(int e, int n);
49
50   /// Extract adjacency data relative to edge [n1,n2]
51   int findAdjData(int n1, int n2, int *e1, int *e2, int *e1n1, int *e1n2, 
52                    int *e1n3, int *e2n1, int *e2n2, int *e2n3, int *n3, 
53                    int *n4);
54   /// Get the other node connectivity on this element
55   int e2n_getNot(int e, int n1, int n2);
56   /// Verifies if n is a node connectivity of this element
57   int n2e_exists(int n, int e);
58   /// Find the element with connectivity n1, n2, n3
59   int findElementWithNodes(int n1, int n2, int n3);
60
61   /// Return the shared index for this node on this chunk
62   int getSharedNodeIdxl(int n, int chk);
63   /// Return the ghost index for this node on this chunk
64   int getGhostNodeIdxl(int n, int chk);
65   /// Return the ghost index for this element on this chunk
66   int getGhostElementIdxl(int e, int chk);
67
68   /// Print all the adjacencies of these nodes and elements
69   void printAdjacencies(int *nodes, int numNodes, int *elems, int numElems);
70
71   /// Is Node 'n1' a fixed node (i.e. defines the shape)
72   bool isFixedNode(int n1);
73   /// Is node 'n1' a corner
74   bool isCorner(int n1);
75   /// Is the edge defined by (n1,n2) on the boundary of the mesh
76   bool isEdgeBoundary(int n1, int n2);
77
78   /// Helper function to perform a Delaunay flip of edge (n1, n2)
79   /** Perform a Delaunay flip of edge (n1, n2) returning 1 if successful, 0 if 
80       not (likely due to the edge being on a boundary).  The convexity of the 
81       quadrilateral formed by two faces incident to edge (n1, n2) is verified. 
82       n1 and n2 are assumed to be local/shared to this chunk. An adjacency test is
83       performed on n1 and n2 by searching for an element with edge [n1,n2]. **/
84   int edge_flip_help(int e1, int e2, int n1, int n2, int e1_n1, 
85                              int e1_n2, int e1_n3, int n3, int n4,int *locknodes);
86   
87   /// Helper function to Bisect edge (n1, n2) and the two adjacent elements
88   /** Given edge e:(n1, n2), remove the two elements (n1,n2,n3) and (n2,n1,n4) 
89       adjacent to e, and bisect e by adding node n5. Add elements (n1,n5,n3), 
90       (n5,n2,n3), (n5,n1,n4) and (n2,n5,n4); returns new node n5. **/
91   int edge_bisect_help(int e1, int e2, int n1, int n2, int e1_n1, 
92                                int e1_n2, int e1_n3, int e2_n1, int e2_n2, 
93                                int e2_n3, int n3, int n4);
94
95   /// Helper function to remove the degree 4 vertex n1 without modifying degree of adj n2
96   /** Inverse of edge bisect, this removes a degree 4 vertex n1 and 2 of its
97       adjacent elements.  n2 indicates that the two elements removed are
98       adjacent to edge [n1,n2]. This could be performed with edge_contraction,
99       but this is a simpler operation.
100       Warning: This function was never tested!! It definitely needs work! */
101   int vertex_remove_help(int e1, int e2, int n1, int n2, int e1_n1, 
102                                  int e1_n2, int e1_n3, int e2_n1, int e2_n2, 
103                                  int e2_n3, int n3, int n4, int n5);
104
105   /// Split a node n into two nodes with an edge in between
106   /** Given a node n and two adjacent nodes n1 and n2, split n into two nodes
107       n and np such that the edges to the neighbors n1 and n2
108       expand into two new elements (n, np, n1) and (np, n, n2);
109       return the id of the newly created node 'np'.
110       Warning: This function was never tested!! It definitely needs work! */
111   int vertex_split(int n, int n1, int n2);
112   /// Helper function to split a node n into two nodes with an edge in between
113   int vertex_split_help(int n, int n1, int n2, int e1, int e3);
114 };
115
116
117 ///Provides primitive mesh modification functions (involves atomic locking/unlocking)
118 /** An adaptivity class which provides the primitive incremental mesh modification operations.
119  * These operations are edge_bisect, edge_flip and edge_contract.
120  * It provides a lock for all the nodes involved in the operation, so
121  * that it does not interfere with any other operation.
122  */
123 class FEM_AdaptL : public FEM_Adapt {
124  public:
125   /// default constructor
126   FEM_AdaptL() {
127     theMesh = NULL; theMod = NULL;
128   }
129   /// Initialize FEM_Adapt with a chunk of the mesh
130   FEM_AdaptL(FEM_Mesh *m, femMeshModify *fm) { theMesh = m; theMod = fm; }
131   /// Initialize FEM_Adapt with the femMeshModify object
132   FEM_AdaptL(femMeshModify *fm) { theMesh = NULL; theMod = fm; }
133   /// Initialize FEM_Adapt with the FEM_Mesh object
134   void FEM_AdaptLSetMesh(FEM_Mesh *m) {theMesh = m;}
135   /// Pup code for this class
136   void pup(PUP::er &p) {
137   }
138
139   /// Lock the following set of read and write nodes
140   int lockNodes(int *gotlocks, int *lockrnodes, int numRNodes, int *lockwnodes, int numWNodes);
141   /// Lock the following set of read and write nodes
142   int unlockNodes(int *gotlocks, int *lockrnodes, int numRNodes, int *lockwnodes, int numWNodes);
143
144   /// Perform a Delaunay flip of edge (n1, n2)
145   int edge_flip(int n1, int n2);
146   /// Bisect edge (n1, n2) and the two adjacent elements
147   int edge_bisect(int n1, int n2);
148   /// Remove the degree 4 vertex n1 without modifying degree of adj n2
149   int vertex_remove(int n1, int n2);
150   /// Contract edge (n1, n2) and the two adjacent elements
151   /** Given and edge e:(n1, n2), determine the two adjacent elements (n1,n2,n3)
152       and (n1,n2,n4). Contract edge e by creating node n5, removing all 
153       elements incident on n1 xor n2 and reinserting with incidence on n5, 
154       removing the two elements (n1,n2,n3) and (n1,n2,n4) adjacent to e, and 
155       finally removing nodes n1 and n2; return 1 if successful, 0 if not **/
156   int edge_contraction(int n1, int n2);
157   /// Helper function for contract edge (n1, n2) and the two adjacent elements
158   int edge_contraction_help(int *e1P, int *e2P, int n1, int n2, int e1_n1, 
159                                     int e1_n2, int e1_n3, int e2_n1, int e2_n2,
160                                     int e2_n3, int n3, int n4);
161
162   /// Acquire an element in our ghost layer, turning it into a local element
163   int eatIntoElement(int e);
164   /// Test the adaptivity system to see if any nodes are locked
165   void residualLockTest();
166   /// Test the mesh for corruption in connectivity/adjacency
167   void structureTest();
168 };
169
170 #endif
171