Merge branch 'charm' of charmgit:charm into charm
[charm.git] / examples / amr / jacobi2Dthesis / jacobi2DAMR.C
1 #include "jacobi2DAMR.h"
2 #include "jacobi2DAMR.decl.h"
3 /*
4 ********************************************
5 User Code for 2D
6 ********************************************
7 */
8 void AmrUserDataJacobiInit(void)
9 {
10   PUPable_reg(AmrUserData);
11   PUPable_reg(Jacobi2DAMR);
12 }
13
14 AmrUserData* AmrUserData :: createData()
15 {
16   Jacobi2DAMR *instance = new Jacobi2DAMR;
17   return (AmrUserData *)instance;
18 }
19   
20 AmrUserData* AmrUserData :: createData(void *data, int dataSize)
21 {
22    Jacobi2DAMR *instance = new Jacobi2DAMR(data , dataSize);
23    return (AmrUserData *) instance;
24 }
25
26 void AmrUserData :: deleteNborData(void* data)
27 {
28   delete [](double *) data;
29 }
30
31 void AmrUserData :: deleteChildData(void* data)
32 {
33   delete [](double *) data;
34 }
35
36 void Jacobi2DAMR :: doComputation(void)
37 {
38   for(int i=1; i <= cellSize ;i++) 
39     for(int j=1; j<=cellSize;j++) 
40       newDataGrid[i][j] = 0.2 * (dataGrid[i][j-1] + dataGrid[i][j+1] 
41                                  +dataGrid[i][j] +dataGrid[i-1][j] +
42                                   dataGrid[i+1][j]);
43   copyGrid();
44   
45 }
46
47 void Jacobi2DAMR :: copyGrid(void) 
48 {
49   for(int i=0; i< cellSize+2; i++)
50     for(int j=0; j<cellSize+2; j++){
51       dataGrid[i][j] = newDataGrid[i][j];
52       newDataGrid[i][j] = 10.0;
53     }
54 }
55
56 void ** Jacobi2DAMR :: getNborMsgArray(int* sizePtr)
57 {
58   //gives the size of each individual column in bytes
59   *sizePtr = cellSize* sizeof(double);
60   //since we are using 2D mesh so have an array of size 4
61   double ** dataArray = new double* [4];
62   for(int i =0;i<4;i++) {
63     dataArray[i] = new double[cellSize];
64   }
65   //To my Right neighbor
66   copyColumn(dataArray[0], cellSize);
67   //To my left neighbor
68   copyColumn(dataArray[1], 1);
69   //To my Down neighbor
70   copyRow(dataArray[2], cellSize);
71   //To my Up neighbor
72   copyRow(dataArray[3], 1);
73   return (void **) dataArray;
74 }
75
76 void **Jacobi2DAMR :: fragmentNborData(void *data, int* sizePtr)
77 {
78   int elements = (*sizePtr)/sizeof(double);
79   int newElements = elements/2;
80   double **fragmentedArray = new double* [2];
81   double *indata = (double *)data;
82   if(elements %2 == 0){
83     *sizePtr = newElements * sizeof(double);
84     for(int i=0; i<2; i++) {
85       fragmentedArray[i] = new double[newElements];
86       for(int j=0; j<newElements;j++)
87         fragmentedArray[i][j] = indata[i*newElements + j];
88     }
89   }
90   else {
91     *sizePtr =( ++newElements)*sizeof(double);
92     for(int i=0; i<2; i++) {
93       fragmentedArray[i] = new double[newElements];
94       for(int j=0; j<newElements-1;j++)
95         fragmentedArray[i][j] = indata[i*newElements + j];
96     }
97     fragmentedArray[1][newElements-1] = indata[elements -1];
98     fragmentedArray[0][newElements-1] = (fragmentedArray[0][newElements -2] 
99                                         + fragmentedArray[1][0])/2;
100   }
101   return (void **)fragmentedArray;
102     
103 }
104
105 void Jacobi2DAMR :: store(void* data , int dataSize , int neighborSide)
106 {
107   if(dataSize/sizeof(double) == cellSize) {
108     switch(neighborSide) {
109     case 0:
110       copyToColumn((double*) data, 0);
111       break;
112     case 1:
113       copyToColumn((double *) data, cellSize+1);
114       break;
115     case 2:
116       copyToRow((double *) data, 0);
117       break;
118     case 3:
119       copyToRow((double *) data, cellSize+1);
120       break;
121     }
122   }
123   //  else
124   //    CkError("Error: Jacobi::store...wrong sized message size %d size/sizeof(double) %d cellsize %d\n",
125   //        dataSize,dataSize/sizeof(double), cellSize);
126 }
127
128 void Jacobi2DAMR :: combineAndStore(void **dataArray, 
129                                         int dataSize,
130                                         int neighborSide) {
131   int size = dataSize /sizeof(double);
132   double * buf = new double[2*size];
133   double *tmpbuf = buf + size;
134   memcpy((void *)buf, dataArray[0], dataSize);
135   memcpy((void *)tmpbuf, dataArray[1], dataSize);
136   store((void *)buf,(2*dataSize),neighborSide);
137   delete []buf;
138 }
139
140 bool Jacobi2DAMR :: refineCriterion(void) 
141 {
142   double average = sumofGrid()/(cellSize*cellSize);
143   if(average < 15.0 && cellSize >= 4)
144     return true;
145   else
146     return false;
147 }
148
149 void** Jacobi2DAMR :: fragmentForRefine(int *sizePtr)
150 {
151   int newSize = cellSize/2;
152   *sizePtr = newSize*newSize*sizeof(double);
153
154   double ** dataArray = new double* [4];
155   for(int i=0;i<4;i++) {
156     dataArray[i] = new double[newSize*newSize];
157     for(int j=1;j<=newSize;j++){
158       for(int k=1;k<=newSize;k++)
159         dataArray[i][(j-1)*newSize+(k-1)] = 
160                 dataGrid[((i/2)%2)*newSize+j][(i%2)*newSize+k];
161     }
162   }
163   return (void **)dataArray;
164   
165 }
166
167 void Jacobi2DAMR::pup(PUP::er &p)
168 {
169   AmrUserData::pup(p);
170   p(cellSize);
171
172   //have to pup dataGrid and newDataGrid here
173   if(p.isUnpacking()) {
174     dataGrid = new double*[cellSize+2];
175     newDataGrid = new double*[cellSize+2];
176     for(int i=0;i<cellSize+2;i++) {
177       dataGrid[i] = new double[cellSize+2];
178       newDataGrid[i] = new double[cellSize+2];
179     }
180   }
181   for(int i=0; i<cellSize+2;i++) {
182     p(dataGrid[i],cellSize+2);
183     p(newDataGrid[i],cellSize+2);
184   }
185 }
186
187 PUPable_def(AmrUserData);
188 PUPable_def(Jacobi2DAMR);
189
190 #include "jacobi2DAMR.def.h"