Exposed some adaptivity functions for use in cpsd
[charm.git] / src / libs / ck-libs / ParFUM / ParFUM_Mesh_Modify.h
1 /* File: fem_mesh_modify.h
2  * Authors: Nilesh Choudhury
3  * 
4  */
5
6 /**
7 This file contains a set of functions, which allow primitive operations upon meshes in parallel. The functions are defined in fem_mesh_modify.C.
8
9 Assumptions:
10
11 The mesh must be in a consistant state before and after these operations:
12 - Any shared node must be in the IDXL table for both the local and 
13 other chunks.
14 - FEM_add_element can only be called with a set of existing local or shared nodes
15 - The mesh must be nice. Each element may be adjacent to at most one other element per face/edge/tuple
16 - The mesh must have e2e, n2n, and n2e adjacencies computed before any of these functions are called.
17 The calls will maintain the adjacency tables, both remotely and locally.
18 - Exactly one ghost layer exists around all chunks before these modification functions are called. 
19 A ghost element is one that is adjacent to at least one shared node. A ghost node is any non-shared 
20 node adjacent to a ghost element. The e2e adjacencies need not have the same definition for 
21 adjacent elements.
22 */
23
24 #ifndef __ParFUM_Mesh_Modify_H
25 #define __ParFUM_Mesh_Modify_H
26
27 //stupid number for maximum number of chunks, but reasonable enough
28 #define MAX_CHUNK 1000000000
29
30 ///Add a node between some adjacent nodes on this mesh
31 int FEM_add_node(FEM_Mesh *m, int* adjacent_nodes=0, int num_adjacent_nodes=0, int *chunks=0, int numChunks=0, int forceShared=0);
32 ///Remove a node on this mesh
33 void FEM_remove_node(FEM_Mesh *m, int node);
34 ///Add an element on this mesh with this connectivity
35 int FEM_add_element(FEM_Mesh *m, int* conn, int conn_size, int elem_type=0, int chunkNo=-1);
36 ///Remove an element on this mesh
37 int FEM_remove_element(FEM_Mesh *m, int element, int elem_type=0, int permanent=-1);
38 ///Purge the element from this mesh (invalidate entry)
39 int FEM_purge_element(FEM_Mesh *m, int element, int elem_type=0);
40
41 // Internal functions used as helper for the above functions
42 ///Update adjacencies for this new node, and attach a lock to it
43 int FEM_add_node_local(FEM_Mesh *m, bool addGhost=false, bool doLocking=true, bool doAdjacencies=true);
44 ///Get rid of idxl entries for this node and clear adjacencies, invalidate node
45 void FEM_remove_node_local(FEM_Mesh *m, int node);
46 ///Update adjacencies for this element and all surrounding nodes/elements
47 int FEM_add_element_local(FEM_Mesh *m, int *conn, int connSize, int elemType, bool addGhost, bool create_adjacencies=1);
48 ///Clear up the adjacencies
49 void FEM_remove_element_local(FEM_Mesh *m, int element, int etype);
50 void FEM_update_new_element_e2e(FEM_Mesh *m, int newEl, int elemType);
51
52 ///Deprecated: locks all chunks for the nodes and elements specified
53 int FEM_Modify_Lock(FEM_Mesh *m, int* affectedNodes=0, int numAffectedNodes=0, int* affectedElts=0, int numAffectedElts=0, int elemtype=0);
54 ///Deprecated: Unlock all chunks that have been locked by this mesh 
55 int FEM_Modify_Unlock(FEM_Mesh *m);
56 ///Lock this node on this mesh with a read/write lock
57 int FEM_Modify_LockN(FEM_Mesh *m, int nodeId, int readLock);
58 ///Lock the read/write lock for this node on this mesh
59 int FEM_Modify_UnlockN(FEM_Mesh *m, int nodeId, int readLock);
60 ///Reassign the lock on a node when a chunk is losing a node
61 void FEM_Modify_LockAll(FEM_Mesh*m, int nodeId, bool lockall=true);
62 ///Update the lock on this node (by locking the newly formed node: Deprecated
63 void FEM_Modify_LockUpdate(FEM_Mesh*m, int nodeId, bool lockall=true);
64 ///For the newly acquired node, correct the lock by removing superfluous locks: Deprecated
65 void FEM_Modify_correctLockN(FEM_Mesh *m, int nodeId);
66
67 ///Get the data for 'length' indices from 'fem_mesh' for the 'attr' of 'entity' starting at index 'firstItem'
68 void FEM_Mesh_dataP(FEM_Mesh *fem_mesh,int entity,int attr,void *data, int firstItem, int length, int datatype,int width);
69 ///Get the data for 'length' indices from 'fem_mesh' for the 'attr' of 'entity' starting at index 'firstItem'
70 void FEM_Mesh_data_layoutP(FEM_Mesh *fem_mesh,int entity,int attr,void *data, int firstItem, int length, IDXL_Layout_t layout);
71 ///Get the data for 'length' indices from 'fem_mesh' for the 'attr' of 'entity' starting at index 'firstItem'
72 void FEM_Mesh_data_layoutP(FEM_Mesh *fem_mesh,int entity,int attr,void *data, int firstItem,int length, const IDXL_Layout &layout);
73
74 ///Copy the essential attributes for this ghost node from remote chunks
75 void FEM_Ghost_Essential_attributes(FEM_Mesh *m, int coord_attr, int bc_attr, int nodeid);
76
77
78
79 ///Message to initialize 'numChunks' and 'chunkIdx' of femMeshModify on all chunks
80 class femMeshModMsg : public CMessage_femMeshModMsg {
81  public:
82   int numChunks;
83   int myChunk;
84
85   femMeshModMsg() {}
86   
87   femMeshModMsg(int num, int idx) {
88     numChunks = num;
89     myChunk = idx;
90   }
91   
92   ~femMeshModMsg() {}
93 };
94
95 ///A Message to encapsulate a boolean
96 class boolMsg : public CMessage_boolMsg {
97  public:
98   bool b;
99
100   boolMsg(bool bo) {
101     b = bo;
102   }
103
104   ~boolMsg() {}
105 };
106
107 ///A message to encapsulate an integer
108 class intMsg : public CMessage_intMsg {
109  public:
110   int i;
111
112   intMsg(int n) {
113     i = n;
114   }
115
116   ~intMsg(){}
117 };
118
119 ///A message to encapsulate two integers
120 class int2Msg : public CMessage_int2Msg {
121  public:
122   int i, j;
123
124   int2Msg(int m, int n) {
125     i = m;
126     j = n;
127   }
128
129   ~int2Msg(){}
130 };
131
132 ///A message to encapsulate two doubles
133 class double2Msg : public CMessage_double2Msg {
134  public:
135   double i,j;
136
137   double2Msg(double m, double n) {
138     i = m;
139     j = n;
140   }
141
142   ~double2Msg() {}
143 };
144
145 ///A message to encapsulate a mesh pointer and a tcharm pointer
146 class FEMMeshMsg : public CMessage_FEMMeshMsg {
147  public:
148   FEM_Mesh *m;
149   TCharm *t;
150         int meshid;
151
152   FEMMeshMsg(FEM_Mesh *mh, TCharm *t1) {
153     m = mh;
154     t = t1;
155   }
156   FEMMeshMsg(FEM_Mesh *mh, TCharm *t1,int _meshid) {
157     m = mh;
158     t = t1;
159                 meshid = _meshid;
160   }
161
162   ~FEMMeshMsg() {}
163 };
164
165 ///A message to pack all the data needed to tell a remote chunk to add a new node
166 class addNodeMsg : public CMessage_addNodeMsg {
167  public:
168   int chk;
169   int nBetween;
170   int *between;
171   int *chunks;
172   int numChunks;
173   int forceShared;
174
175   ~addNodeMsg() {
176     if(between) {
177       //delete between;
178       //delete chunks;
179     }
180   }
181 };
182
183 ///A message used to tell a remote chunk to add a shared node
184 class sharedNodeMsg : public CMessage_sharedNodeMsg {
185  public:
186   int chk;
187   int nBetween;
188   int *between;
189
190   ~sharedNodeMsg() {
191     //if(between!=NULL) {
192     //delete between;
193     //}
194   }
195 };
196
197 ///A message to tell a remote chunk to remove a shared node
198 class removeSharedNodeMsg : public CMessage_removeSharedNodeMsg {
199  public:
200   int chk;
201   int index;
202 };
203
204 ///A message to tell a remote chunk to add a ghost element (all data is packed)
205 class addGhostElemMsg : public CMessage_addGhostElemMsg {
206  public:
207   int chk;
208   int elemType;
209   int *indices;
210   int *typeOfIndex;
211   int connSize;
212
213   ~addGhostElemMsg() {
214     //if(indices!=NULL) {
215     //delete indices;
216     //}
217     //if(typeOfIndex!=NULL) {
218     //delete typeOfIndex;
219     //}
220   }
221 };
222
223 ///A message to return data about the chunks that share/ghost a node/element
224 class chunkListMsg : public CMessage_chunkListMsg {
225  public:
226   int numChunkList;
227   int *chunkList;
228   int *indexList;
229
230   ~chunkListMsg() {
231     if(numChunkList>0) {
232       //delete chunkList;
233       //delete indexList;
234     }
235   }
236 };
237
238 ///A message to pack all data to tell a remote chunk to add an element
239 class addElemMsg : public CMessage_addElemMsg {
240  public:
241   int chk;
242   int elemtype;
243   int connSize;
244   int *conn;
245   int numGhostIndex;
246   int *ghostIndices;
247
248   ~addElemMsg() {
249     if(conn) {
250       //delete conn;
251     }
252     if(ghostIndices) {
253       //delete ghostIndices;
254     }
255   }
256 };
257
258 ///A message to tell a remote chunk to remove a ghost element and some IDXL list entries
259 class removeGhostElemMsg : public CMessage_removeGhostElemMsg {
260  public:
261   int chk;
262   int elemtype;
263   int elementid;
264   int numGhostIndex;
265   int numGhostRNIndex;
266   int numGhostREIndex;
267   int numSharedIndex;
268   int *ghostIndices;
269   int *ghostRNIndices;
270   int *ghostREIndices;
271   int *sharedIndices;
272
273   ~removeGhostElemMsg() {
274     if(ghostIndices!=NULL) {
275       //   delete ghostIndices;
276       //   delete ghostRNIndices;
277       //    delete ghostREIndices;
278       //    delete sharedIndices;
279     }
280   }
281 };
282
283 ///A message to tell a remote chunk to remove an element
284 class removeElemMsg : public CMessage_removeElemMsg {
285  public:
286   int chk;
287   int elementid;
288   int elemtype;
289   int permanent;
290 };
291
292 ///A message to verify if the IDXL entries for a node/element on one chunk is consistent with another chunk
293 class verifyghostsendMsg : public CMessage_verifyghostsendMsg {
294  public:
295   int fromChk;
296   int sharedIdx;
297   int numchks;
298   int *chunks;
299
300   verifyghostsendMsg() {
301   }
302   
303   ~verifyghostsendMsg() {
304     //if(chunks!=NULL) delete chunks;
305   }
306 };
307
308 ///A message that packs the indices of a bunch of chunks (used for ghost send)
309 class findgsMsg : public CMessage_findgsMsg {
310  public:
311   int numchks;
312   int *chunks;
313   
314   ~findgsMsg() {
315   }
316 };
317
318 ///A message that packs all data for a node/element
319 class entDataMsg : public CMessage_entDataMsg {
320  public:
321   char *data;
322   int datasize;
323   int memsize;
324
325   entDataMsg(int size, int msize) {
326     datasize = size;
327     memsize = msize;
328   }
329 };
330
331 ///A message that packs all attributes for a node
332 class updateAttrsMsg : public CMessage_updateAttrsMsg {
333  public:
334   char *data;
335   int datasize;
336   int fromChk;
337   int sharedIdx;
338   bool isnode;
339   bool isGhost;
340   int elemType;
341
342   updateAttrsMsg(int size) {
343     datasize = size;
344     isnode = false;
345     isGhost = false;
346     elemType = 0;
347   }
348 };
349
350
351
352
353 class FEM_Interpolate;
354
355 ///The shadow array attached to a fem chunk to perform all communication during adaptivity
356 /** This data structure maintains some adaptivity information, along with
357     locks for nodes and idxl lists. It handles all the remote function calls
358     and uses FEM_MUtil to perform most of the operations.
359  */
360 class femMeshModify : public CBase_femMeshModify {
361   friend class FEM_lock;
362   friend class FEM_MUtil;
363   friend class FEM_Mesh;
364   friend class FEM_Interpolate;
365   friend class FEM_Adapt;
366   friend class FEM_AdaptL;
367   friend class FEM_Adapt_Algs;
368
369  public:
370   ///Total number of chunks
371   int numChunks;
372   ///Index of this chunk (the chunk this is attached to)
373   int idx;
374   ///The Tcharm pointer to set it even outside the thread..
375   TCharm *tc;
376   ///The proxy for the current Tcharm object
377   CProxy_TCharm tproxy;
378   ///cross-pointer to the fem mesh on this chunk
379   FEM_Mesh *fmMesh;
380   ///Deprecated: used to lock this chunk
381   FEM_lock *fmLock;
382   ///Set of locks for all nodes on this chunk
383   CkVec<FEM_lockN> fmLockN;
384   ///Set of locks for all idxl lists
385   /** each chunk can have numChunks*5 idxl lists, but numChunks locks. 
386    */
387   CkVec<bool> fmIdxlLock;
388   ///The list of fixed nodes
389   /** this list is populated initially, and never changes (defines shape)
390    */
391   CkVec<int> fmfixedNodes;
392   ///Pointer to the utility object (performs most adaptive utilities)
393   FEM_MUtil *fmUtil;
394   ///Pointer to the object that performs the interpolations
395   FEM_Interpolate *fmInp;
396   ///Deprecated: Pointer to the FEM_Adapt object
397   FEM_Adapt *fmAdapt;
398   ///Pointer to the object that performs the primitive adaptive operations
399   FEM_AdaptL *fmAdaptL;
400   ///Pointer to the object that performs the adaptive algorithms
401   FEM_Adapt_Algs *fmAdaptAlgs;
402
403  public:
404   ///constructor
405   femMeshModify(femMeshModMsg *fm);
406   ///constructor for migration
407   femMeshModify(CkMigrateMessage *m);
408   ///destructor
409   ~femMeshModify();
410
411   ///Pup to transfer this object's data
412   void pup(PUP::er &p);
413   ///This function is overloaded, it is called on this object just after migration
414   void ckJustMigrated(void);
415   ///Set the mesh pointer after the migration
416   void setPointersAfterMigrate(FEM_Mesh *m);
417
418   ///Initialize the mesh pointer for this chunk
419   void setFemMesh(FEMMeshMsg *fm);
420
421   ///Deprecated: Try to lock this node on this chunk (the node index is local to this chunk)
422   intMsg *lockRemoteChunk(int2Msg *i2msg);
423   ///Deprecated: Unlock the node on this chunk (the node index is local to this chunk)
424   intMsg *unlockRemoteChunk(int2Msg *i2msg);
425   ///Try to lock this node on this chunk (receives a shared/ghost index)
426   intMsg *lockRemoteNode(int sharedIdx, int fromChk, int isGhost, int readLock);
427   ///Unlock this node on this chunk (receives a shared/ghost index)
428   intMsg *unlockRemoteNode(int sharedIdx, int fromChk, int isGhost, int readLock);
429
430   ///Get number of chunks
431   int getNumChunks(){return numChunks;}
432   ///Get the index of this chunk
433   int getIdx(){return idx;}
434   ///Get the pointer to the mesh object
435   FEM_Mesh *getfmMesh(){return fmMesh;}
436   ///Deprecated: Get the pointer to the lock-chunk object
437   FEM_lock *getfmLock(){return fmLock;}
438   ///Get the status of the lock for this node
439   FEM_lockN getfmLockN(int nodeid){
440     /*if(!FEM_Is_ghost_index(nodeid)) {
441       return fmLockN[nodeid];
442       } else {
443       return fmgLockN[FEM_To_ghost_index(nodeid)];
444       }*/
445     CkAssert(nodeid < fmLockN.size());
446     return fmLockN[nodeid];
447   }
448   ///Get the pointer to the utility object on this chunk
449   FEM_MUtil *getfmUtil(){return fmUtil;}
450   ///Deprecated: Get the pointer to the primitive operation object
451   FEM_Adapt *getfmAdapt(){return fmAdapt;}
452   ///Get the pointer to the object that encapsulates the primitive adaptive operations
453   FEM_AdaptL *getfmAdaptL(){return fmAdaptL;}
454   ///Get the pointer to the object that encapsulates the adaptive algorithms
455   FEM_Adapt_Algs *getfmAdaptAlgs(){return fmAdaptAlgs;}
456   ///Get the pointer to the interpolate object
457   FEM_Interpolate *getfmInp(){return fmInp;}
458
459   ///Get the list of chunks that share this node
460   chunkListMsg *getChunksSharingGhostNode(int2Msg *);
461
462   ///Add a node on this chunk
463   intMsg *addNodeRemote(addNodeMsg *fm);
464   ///Add a shared node on this chunk
465   void addSharedNodeRemote(sharedNodeMsg *fm);
466   ///Remove a shared node on this chunk
467   void removeSharedNodeRemote(removeSharedNodeMsg *fm);
468   ///Remove a ghost node on this chunk
469   void removeGhostNode(int fromChk, int sharedIdx);
470
471   ///Add a ghost element on this chunk
472   void addGhostElem(addGhostElemMsg *fm);
473   ///Add a local element on this chunk
474   intMsg *addElementRemote(addElemMsg *fm);
475   ///Remove a ghost element on this chunk
476   void removeGhostElem(removeGhostElemMsg *fm);
477   ///Remove a local element on this chunk
478   void removeElementRemote(removeElemMsg *fm);
479
480   ///Acquire this element from 'fromChk'
481   intMsg *eatIntoElement(int fromChk, int sharedIdx);
482   
483   ///Get the owner of the lock for this shared node
484   intMsg *getLockOwner(int fromChk, int sharedIdx);
485   ///Does this chunk send this as a ghost to 'toChk'
486   boolMsg *knowsAbtNode(int fromChk, int toChk, int sharedIdx);
487
488   ///propagate a flip operation across chunks
489   void refine_flip_element_leb(int fromChk, int propElemT, int propNodeT,
490                                int newNodeT, int nbrOpNodeT, int nbrghost,
491                                double longEdgeLen);
492
493   ///add this node to the shared idxl lists for 'fromChk'
494   void addToSharedList(int fromChk, int sharedIdx);
495   ///update the attributes of the node with this data
496   void updateAttrs(updateAttrsMsg *umsg);
497   ///get rid of unnecessary node sends to some chunks for a node
498   void updateghostsend(verifyghostsendMsg *vmsg);
499   ///find the set of chunks where this node should be sent as a ghost
500   findgsMsg *findghostsend(int fromChk, int sharedIdx);
501   ///return the shared index on the ghost send list for chunk 'toChk'
502   intMsg *getIdxGhostSend(int fromChk, int idxshared, int toChk);
503
504   ///Get the coordinates for this node
505   double2Msg *getRemoteCoord(int fromChk, int ghostIdx);
506   ///Get the boundary variable for this node
507   intMsg *getRemoteBound(int fromChk, int ghostIdx);
508
509   ///find the ghost received from 'transChk' at index 'idxTrans' and add this ghost as received from 'fromChk'
510   void updateIdxlList(int fromChk, int idxTrans, int transChk);
511   ///remove this node from this idxl list of chunk 'fromChk'
512   void removeIDXLRemote(int fromChk, int sharedIdx, int type);
513   ///find the shared node with 'transChk' at index 'sharedIdx' and send this as a ghost to 'fromChk'
514   void addTransIDXLRemote(int fromChk, int sharedIdx, int type);
515   ///verify that the size of the idxl list is same on this chunk and 'fromChk'
516   void verifyIdxlList(int fromChk, int size, int type);
517
518   ///lock the idxl list for 'fromChk' on this chunk (blocking call)
519   void idxllockRemote(int fromChk, int type);
520   ///unlock the idxl list for 'fromChk' on this chunk
521   void idxlunlockRemote(int fromChk, int type);
522
523   ///Return the lock owner for this node if there is one (return -1 otherwise)
524   intMsg *hasLockRemoteNode(int sharedIdx, int fromChk, int isGhost);
525   ///Reassign lock on this node
526   void modifyLockAll(int fromChk, int sharedIdx);
527   ///verify that this lock is locked on the smallest chunk
528   boolMsg *verifyLock(int fromChk, int sharedIdx, int isGhost);
529   ///Verify that the number of chunks I get this node as a ghost is same as the number of chunnks that this node is shared on
530   void verifyghostsend(verifyghostsendMsg *vmsg);
531   ///Should this node be send as a ghost from this chunk to 'fromChk' (if no, return true)
532   boolMsg *shouldLoseGhost(int fromChk, int sharedIdx, int toChk);
533
534   ///If this node is not in the ghostSend list add it on the idxl lists on both chunks
535   void addghostsendl(int fromChk, int sharedIdx, int toChk, int transIdx);
536   ///add this node to the idxl ghost recv list of this chunk
537   void addghostsendl1(int fromChk, int transChk, int transIdx);
538   ///Add the node as a ghostRecv from 'toChk'
539   void addghostsendr(int fromChk, int sharedIdx, int toChk, int transIdx);
540   ///Add this node on the ghostSend list with 'fromChk'
541   void addghostsendr1(int fromChk, int transChk, int transIdx);
542   ///Will it lose this element as a ghost send to 'fromChk'
543   boolMsg *willItLose(int fromChk, int sharedIdx);
544
545   ///The element data is copied from the first element to the second
546   void interpolateElemCopy(int fromChk, int sharedIdx1, int sharedIdx2);
547   ///Remove this ghost element from the ghostRecv idxl list and delete the ghost node
548   void cleanupIDXL(int fromChk, int sharedIdx);
549   ///Purge this element on this chunk
550   void purgeElement(int fromChk, int sharedIdx);
551   ///Pack the data from this element/node and return it
552   entDataMsg *packEntData(int fromChk, int sharedIdx, bool isnode=false, int elemType=0);
553   ///Is this node a fixed node on this chunk
554   boolMsg *isFixedNodeRemote(int fromChk, int sharedIdx);
555
556   //debugging helper function
557   void finish1(void);
558   //debugging helper function
559   void finish(void);
560 };
561 // end mesh_modify.h
562
563 #endif