2D version of the example "Molecular". It has been changed so that it
authorAbhinav Bhatele <bhatele@illinois.edu>
Thu, 31 Jul 2008 19:54:44 +0000 (19:54 +0000)
committerAbhinav Bhatele <bhatele@illinois.edu>
Thu, 31 Jul 2008 19:54:44 +0000 (19:54 +0000)
is in terms of computes and patches. It has a bug due to CkArrayIndex
with -O2

examples/charm++/Molecular2D/Compute.C [new file with mode: 0644]
examples/charm++/Molecular2D/Compute.h [new file with mode: 0644]
examples/charm++/Molecular2D/Makefile [new file with mode: 0644]
examples/charm++/Molecular2D/Patch.C [new file with mode: 0644]
examples/charm++/Molecular2D/Patch.ci [new file with mode: 0644]
examples/charm++/Molecular2D/Patch.h [new file with mode: 0644]
examples/charm++/Molecular2D/common.h [new file with mode: 0644]

diff --git a/examples/charm++/Molecular2D/Compute.C b/examples/charm++/Molecular2D/Compute.C
new file mode 100644 (file)
index 0000000..7ca0717
--- /dev/null
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * $Source$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *****************************************************************************/
+
+/** \file Compute.h
+ *  Author: Abhinav S Bhatele
+ *  Date Created: July 1st, 2008
+ *
+ */
+
+#include "common.h"
+#include "liveViz.h"
+#include "Patch.decl.h"
+#include "Compute.h"
+
+extern /* readonly */ CProxy_Main mainProxy;
+extern /* readonly */ CProxy_Patch patchArray;
+extern /* readonly */ CProxy_Compute computeArray;
+
+extern /* readonly */ int numParts;
+extern /* readonly */ int m; // Number of Chare Rows
+extern /* readonly */ int n; // Number of Chare Columns
+extern /* readonly */ int L; 
+extern /* readonly */ double radius;
+extern /* readonly */ int finalStepCount; 
+
+extern double A; // Force Calculation parameter 1
+extern double B; // Force Calculation parameter 2
+
+// Compute - Default constructor
+Compute::Compute() {
+  cellCount = 0;
+  bufferedX = 0;
+  bufferedY = 0;
+}
+
+Compute::Compute(CkMigrateMessage *msg) { }
+  
+// Function to receive vector of particles
+void Compute::interact(CkVec<Particle> particles, int x, int y ) {
+
+  int i;
+
+  // self interaction check
+  if( thisIndex.x == thisIndex.z && thisIndex.y == thisIndex.w ) {
+    interact(particles,particles);
+    patchArray( x, y).updateForces(particles);
+  } else {
+    if(cellCount == 0) {
+      bufferedX = x;
+      bufferedY = y;
+      bufferedParticles = particles;
+      cellCount++;
+    } else if (cellCount == 1) {
+      // if both particle sets are received, compute interaction
+      cellCount = 0;
+      interact(bufferedParticles,particles);
+      patchArray(bufferedX, bufferedY).updateForces(bufferedParticles);
+      patchArray(x, y).updateForces(particles);
+    }
+  }
+}
+
+// Function to compute all the interactions between pairs of particles in two sets
+void Compute::interact(CkVec<Particle> &first, CkVec<Particle> &second){
+  int i, j;
+  for(i = 0; i < first.length(); i++)
+    for(j = 0; j < second.length(); j++)
+      interact(first[i], second[j]);
+}
+
+// Function for computing interaction among two particles
+// There is an extra test for interaction of identical particles, in which case there is no effect
+void Compute::interact(Particle &first, Particle &second){
+  float rx,ry,rz,r,fx,fy,fz,f;
+
+  // computing base values
+  rx = first.x - second.x;
+  ry = first.y - second.y;
+  r = sqrt(rx*rx + ry*ry);
+
+  // We include 0.000001 to ensure that r doesn't tend to zero in the force calculation
+  // if(r < 0.000001 || r >= DEFAULT_RADIUS)
+  if(r < 0.000001 || r >= L)
+    return;
+
+  f = A / pow(r,12) - B / pow(r,6);
+  fx = f * rx / r;
+  fy = f * ry / r;
+
+  // updating particle properties
+  second.fx -= fx;
+  second.fy -= fy;
+  first.fx += fx;
+  first.fy += fy;
+}
+
diff --git a/examples/charm++/Molecular2D/Compute.h b/examples/charm++/Molecular2D/Compute.h
new file mode 100644 (file)
index 0000000..ed778c7
--- /dev/null
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * $Source$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *****************************************************************************/
+
+/** \file Compute.h
+ *  Author: Abhinav S Bhatele
+ *  Date Created: July 1st, 2008
+ *
+ */
+
+#ifndef __COMPUTE_H__
+#define __COMPUTE_H__
+
+#include "common.h"
+
+// Class representing the interaction agents between a couple of cells
+class Compute : public CBase_Compute {
+  private:
+    int cellCount;  // to count the number of interact() calls
+    CkVec<Particle> bufferedParticles;
+    int bufferedX;
+    int bufferedY;
+
+    void interact(CkVec<Particle> &first, CkVec<Particle> &second);
+    void interact(Particle &first, Particle &second);
+
+  public:
+    Compute();
+    Compute(CkMigrateMessage *msg);
+
+    void interact(CkVec<Particle> particles, int i, int j);
+
+};
+
+#endif
diff --git a/examples/charm++/Molecular2D/Makefile b/examples/charm++/Molecular2D/Makefile
new file mode 100644 (file)
index 0000000..7fd3224
--- /dev/null
@@ -0,0 +1,19 @@
+CHARMC =../../../bin/charmc $(OPTS)
+OPTS   = -g
+
+all: mol3d
+
+mol3d: Patch.o Compute.o
+       $(CHARMC) -language charm++ -o mol3d Patch.o Compute.o
+
+Patch.o: Patch.C Patch.h Patch.decl.h common.h
+       $(CHARMC) -o Patch.o Patch.C
+
+Patch.decl.h: Patch.ci
+       $(CHARMC) Patch.ci
+
+Compute.o: Compute.C Compute.h Patch.decl.h common.h
+       $(CHARMC) -o Compute.o Compute.C
+
+clean:
+       rm -f *.decl.h *.def.h *.o mol3d charmrun
diff --git a/examples/charm++/Molecular2D/Patch.C b/examples/charm++/Molecular2D/Patch.C
new file mode 100644 (file)
index 0000000..66c32cb
--- /dev/null
@@ -0,0 +1,520 @@
+/*****************************************************************************
+ * $Source$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *****************************************************************************/
+
+/** \file Patch.C
+ *  Author: Abhinav S Bhatele
+ *  Date Created: July 1st, 2008
+ *
+ */
+
+#include "time.h"
+#include "common.h"
+#include "liveViz.h"
+#include "Patch.decl.h"
+#include "Patch.h"
+#include "Compute.h"
+
+/* readonly */ CProxy_Main mainProxy;
+/* readonly */ CProxy_Patch patchArray;
+/* readonly */ CProxy_Compute computeArray;
+
+/* readonly */ int numParts;
+/* readonly */ int m; // Number of Chare Rows
+/* readonly */ int n; // Number of Chare Columns
+/* readonly */ int L; 
+/* readonly */ double radius;
+/* readonly */ int finalStepCount; 
+
+double A = 2.0; // Force Calculation parameter 1
+double B = 1.0; // Force Calculation parameter 2
+
+// Entry point of Charm++ application
+Main::Main(CkArgMsg* msg) {
+  int i, j, k, l;  
+
+  numParts = DEFAULT_PARTICLES;
+  m = DEFAULT_M;
+  n = DEFAULT_N;
+  L = DEFAULT_L;
+  radius = DEFAULT_RADIUS;
+  finalStepCount = DEFAULT_FINALSTEPCOUNT;
+
+  delete msg;
+  checkInCount = 0;
+
+  mainProxy = thisProxy;
+
+  // initializing the cell 2D array
+  patchArray = CProxy_Patch::ckNew(m,n);
+  CkPrintf("patches inserted\n");
+
+  // initializing the interaction 4D array
+  computeArray = CProxy_Compute::ckNew();
+  // For Round Robin insertion
+  int numPes = CkNumPes();
+  int currPE = -1;
+  int check[m][n][m][n];
+  
+  for (int x = 0; x < m; x++ )
+    for (int y = 0; y < n; y++ )
+      for (int z = 0; z < m; z++ )
+       for (int w = 0; w < n; w++ )
+         check[x][y][z][w] = 0;
+
+
+  for (int x = 0; x < m ; x++ ) {
+    for (int y = 0; y < n; y++ ) {
+
+      // self interaction
+      if(check[x][y][x][y])
+       CkPrintf("error %d %d %d %d\n", x, y, x, y);
+      else
+       check[x][y][x][y] = 1;
+      computeArray( x, y, x, y ).insert( (currPE++) % numPes );
+
+      // (x,y) and (x+1,y) pair
+      (x == m-1) ? (i=0, k=x) : (i=x, k=x+1);
+      if(check[i][y][k][y])
+       CkPrintf("error %d %d %d %d\n", i, y, k, y);
+      else
+       check[i][y][k][y] = 1;
+      computeArray( i, y, k, y ).insert( (currPE++) % numPes );
+
+      // (x,y) and (x,y+1) pair
+      (y == n-1) ? (j=0, l=y) : (j=y, l=y+1);
+      if(check[x][j][x][l])
+       CkPrintf("error %d %d %d %d\n", x, j, x, l);
+      else
+       check[x][j][x][l] = 1;
+      computeArray( x, j, x, l ).insert( (currPE++) % numPes );
+
+      // (x,y) and (x+1,y+1) pair, Irrespective of y
+      (x == m-1) ? ( i=0, k=x, j=(y+1)%n, l=y ) : (i=x, k=x+1, j=y, l=(y+1)%n );
+      if(check[i][j][k][l])
+       CkPrintf("error %d %d %d %d\n", i, j, k, l);
+      else
+       check[i][j][k][l] = 1;
+      computeArray( i, j, k, l ).insert( (currPE++) % numPes );
+
+      // (x,y) and (x-1,y+1) pair
+      (x == 0) ? ( i=x, k=(x-1+m)%m, j=y, l=(y+1)%n ) : (i=x-1, k=x, j=(y+1)%n, l=y );
+      if(check[i][j][k][l])
+       CkPrintf("error %d %d %d %d\n", i, j, k, l);
+      else
+       check[i][j][k][l] = 1;
+      computeArray( i, j, k, l ).insert( (currPE++) % numPes );
+
+    }
+  }
+
+  computeArray.doneInserting();
+  CkPrintf("computes inserted\n");
+
+  // setup liveviz
+  // CkCallback c(CkIndex_Patch::requestNextFrame(0),patchArray);
+  // liveVizConfig cfg(liveVizConfig::pix_color,true);
+  // liveVizInit(cfg,patchArray,c);
+
+  // sleep(1);
+  CkPrintf("computes start");
+  patchArray.start();
+}
+
+
+// Constructor for chare object migration
+Main::Main(CkMigrateMessage* msg) { }
+
+void Main::checkIn() {
+  checkInCount ++;
+  if( checkInCount > 0)
+    CkExit();
+}
+
+// Default constructor
+Patch::Patch() {
+  int i;
+
+  // starting random generator
+  srand48( thisIndex.x * 1000 + thisIndex.y +time(NULL));
+
+  /* Particle initialization */
+  for(i = 0; i < numParts / (m * n); i++){
+    particles.push_back(Particle());
+
+    particles[i].x = drand48() * L + thisIndex.x * L;
+    particles[i].y = drand48() * L + thisIndex.y * L;
+    particles[i].vx = (drand48() - 0.5) * .2 * MAX_VELOCITY;
+    particles[i].vy = (drand48() - 0.5) * .2 * MAX_VELOCITY;
+    particles[i].id = (thisIndex.x*m + thisIndex.y) * numParts / (m*n)  + i;
+
+    /* particles[i].x = 0.0 + thisIndex.x * L;
+    particles[i].y = (float) i* 0.9 * L + thisIndex.y * L;
+    particles[i].vx = (drand48() - 0.5) * .2 * MAX_VELOCITY;
+    particles[i].vy = 0.0;
+    particles[i].id = (thisIndex.x*m + thisIndex.y) * numParts / (m*n)  + i; */
+  }    
+
+  updateCount = 0;
+  forceCount = 0;
+  stepCount = 0;
+  updateFlag = false;
+  incomingFlag = false;
+  incomingParticles.resize(0);
+}
+
+// Constructor for chare object migration
+Patch::Patch(CkMigrateMessage *msg) { }  
+                                       
+Patch::~Patch() {}
+
+// Function to start interaction among particles in neighboring cells as well as its own particles
+void Patch::start() {
+
+  int x = thisIndex.x;
+  int y = thisIndex.y;
+  int i, j, k, l;
+  
+  // self interaction
+  computeArray( x, y, x, y).interact(particles, x, y);
+
+  // interaction with (x-1, y-1)
+  (x == 0) ? ( i=x, k=(x-1+m)%m, j=y, l=(y-1+n)%n ) : (i=x-1, k=x, j=(y-1+n)%n, l=y);
+  computeArray( i, j, k, l ).interact(particles, x, y);
+
+  // interaction with (x-1, y)
+  (x == 0) ? (i=x, k=(x-1+m)%m) : (i=x-1, k=x);
+  computeArray( i, y, k, y).interact(particles, x, y);
+
+  // interaction with (x-1, y+1)
+  (x == 0) ? ( i=x, k=(x-1+m)%m, j=y, l=(y+1)%n ) : (i=x-1, k=x, j=(y+1)%n, l=y);
+  computeArray( i, j, k, l ).interact(particles, x, y);
+
+  // interaction with (x, y-1)
+  (y == 0) ? (j=y, l=(y-1+n)%n) : (j=y-1, l=y);
+  computeArray( x, j, x, l ).interact(particles, x, y);
+
+  // interaction with (x, y+1)
+  (y == n-1) ? (j=(y+1)%n, l=y) : (j=y, l=y+1);// compute
+  computeArray( x, j, x, l ).interact(particles, x, y);
+
+  // interaction with (x+1, y-1)
+  (x == m-1) ? ( i=0, k=x, j=(y-1+n)%n, l=y ) : (i=x, k=x+1, j=y, l=(y-1+n)%n );
+  computeArray( i, j, k, l ).interact(particles, x, y);
+
+  // interaction with (x+1, y)
+  (x == m-1) ? (i=0, k=x) : (i=x, k=x+1);
+  computeArray( i, y, k, y).interact(particles, x, y);
+
+  // interaction with (x+1, y+1)
+  (x == m-1) ? ( i=0, k=x, j=(y+1)%n, l=y ) : (i=x, k=x+1, j=y, l=(y+1)%n );
+  computeArray( i, j, k, l ).interact(particles, x, y);
+
+}
+
+// Function to update forces coming from a neighbor interaction chare
+void Patch::updateForces(CkVec<Particle> &updates) {
+  int i, x ,y;
+  CkVec<Particle> outgoing;
+
+  // incrementing the counter for receiving updates
+  forceCount++;
+
+  // updating force information
+  for(i = 0; i < updates.length(); i++){
+    particles[i].fx += updates[i].fx;
+    particles[i].fy += updates[i].fy;
+  }
+
+  // if all forces are received, then it must recompute particles location
+  if( forceCount >= 9) {
+    // Received all it's forces from the interactions.
+    forceCount = 0;
+  
+    // Update properties on own particles
+    updateProperties();
+
+    // sending particles to neighboring cells
+    x = thisIndex.x;
+    y = thisIndex.y;
+
+    // particles sent to (x-1,y-1)             
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if (particles[i].x < x*L && particles[i].y < y*L) {
+       outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x-1+m)%m,(y-1+n)%n).updateParticles(outgoing);
+         
+    // particles sent to (x-1,y)               
+    outgoing.removeAll();
+    i = 0;
+    while (i < particles.length()) {
+      if(particles[i].x < x*L && particles[i].y <= (y+1)*L){
+       outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x-1+m)%m,y).updateParticles(outgoing);
+
+    // particles sent to (x-1,y+1)
+    outgoing.removeAll();
+    i = 0;
+    while (i < particles.length()) {
+      if(particles[i].x < x*L && particles[i].y > (y+1)*L){
+       outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x-1+m)%m,(y+1)%n).updateParticles(outgoing);
+
+    // particles sent to (x+1,y-1)
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if(particles[i].x > (x+1)*L && particles[i].y < y*L){
+        outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x+1)%m,(y-1+n)%n).updateParticles(outgoing);
+
+    // particles sent to (x+1,y)
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if(particles[i].x > (x+1)*L && particles[i].y <= (y+1)*L){
+        outgoing.push_back(wrapAround(particles[i]));
+        particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x+1)%m,y).updateParticles(outgoing);
+
+    // particles sent to (x+1,y+1)
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if(particles[i].x > (x+1)*L && particles[i].y > (y+1)*L){
+        outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray((x+1)%m,(y+1)%n).updateParticles(outgoing);
+
+    // particles sent to (x,y-1)
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if(particles[i].y < y*L){
+       outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray(x,(y-1+n)%n).updateParticles(outgoing);
+
+    // particles sent to (x,y+1)
+    outgoing.removeAll();
+    i = 0;
+    while(i < particles.length()){
+      if(particles[i].y > (y+1)*L){
+        outgoing.push_back(wrapAround(particles[i]));
+       particles.remove(i);
+      } else
+       i++;
+    }
+    patchArray(x,(y+1)%n).updateParticles(outgoing);
+
+    outgoing.removeAll();
+
+    updateFlag = true;
+             
+    // checking whether to proceed with next step
+    checkNextStep();
+  }
+  
+}
+
+// Function that checks whether it must start the following step or wait until other messages are received
+void Patch::checkNextStep(){
+  int i;
+  if(CkMyPe() == 0)
+  CkPrintf("Step %d\n", stepCount);
+
+  if(updateFlag && incomingFlag) {
+    // resetting flags
+    updateFlag = false;
+    incomingFlag = false;
+    stepCount++;
+
+    // adding new elements
+    for(i = 0; i < incomingParticles.length(); i++){
+      particles.push_back(incomingParticles[i]);
+    }
+    incomingParticles.removeAll();
+
+    // checking for next step
+    if(stepCount >= finalStepCount) {
+      print();
+      mainProxy.checkIn();
+    } else {
+      thisProxy( thisIndex.x, thisIndex.y ).start();
+    }
+  }
+}
+
+// Function that receives a set of particles and updates the 
+// forces of them into the local set
+void Patch::updateParticles(CkVec<Particle> &updates) {
+  updateCount++;
+
+  for( int i=0; i < updates.length(); i++) {
+    incomingParticles.push_back(updates[i]);
+  }
+
+  // if all the incoming particle updates have been received, we must check 
+  // whether to proceed with next step
+  if(updateCount >= 8 ) {
+    updateCount = 0;
+    incomingFlag = true;
+    checkNextStep();
+  }
+}
+
+// Function to update properties (i.e. acceleration, velocity and position) in particles
+void Patch::updateProperties(){
+  int i;
+  double xDisp, yDisp;
+       
+  for(i = 0; i < particles.length(); i++) {
+    // applying kinetic equations
+    particles[i].ax = particles[i].fx / DEFAULT_MASS;
+    particles[i].ay = particles[i].fy / DEFAULT_MASS;
+    particles[i].vx = particles[i].vx + particles[i].ax * DEFAULT_DELTA;
+    particles[i].vy = particles[i].vy + particles[i].ay * DEFAULT_DELTA;
+
+    limitVelocity( particles[i] );
+
+    particles[i].x = particles[i].x + particles[i].vx * DEFAULT_DELTA;
+    particles[i].y = particles[i].y + particles[i].vy * DEFAULT_DELTA;
+
+    particles[i].fx = 0.0;
+    particles[i].fy = 0.0;
+  }
+}
+
+void Patch::limitVelocity(Particle &p) {
+  //if( fabs(p.vx * DEFAULT_DELTA) > DEFAULT_RADIUS ) {
+  if( fabs( p.vx ) > MAX_VELOCITY ) {
+    //if( p.vx * DEFAULT_DELTA < 0.0 )
+    if( p.vx < 0.0 )
+      p.vx = -MAX_VELOCITY;
+    else
+      p.vx = MAX_VELOCITY;
+  }
+
+  //if( fabs(p.vy * DEFAULT_DELTA) > DEFAULT_RADIUS ) {
+  if( fabs(p.vy) > MAX_VELOCITY ) {
+    //if( p.vy * DEFAULT_DELTA < 0.0 )
+    if( p.vy < 0.0 )
+      p.vy = -MAX_VELOCITY;
+    else
+      p.vy = MAX_VELOCITY;
+  }
+}
+
+Particle& Patch::wrapAround(Particle &p) {
+  if(p.x < 0.0) p.x += L*m;
+  if(p.y < 0.0) p.y += L*n;
+  if(p.x > L*m) p.x -= L*m;
+  if(p.y > L*n) p.y -= L*n;
+
+  return p;
+}
+
+// Helper function to help with LiveViz
+void color_pixel(unsigned char*buf,int width, int height, int xpos,int ypos,
+                             unsigned char R,unsigned char G,unsigned char B) {
+  if(xpos>=0 && xpos<width && ypos>=0 && ypos<height) {
+    buf[3*(ypos*width+xpos)+0] = R; 
+    buf[3*(ypos*width+xpos)+1] = G; 
+    buf[3*(ypos*width+xpos)+2] = B; 
+  }
+}
+    
+// Each chare provides its particle data to LiveViz
+/*void Patch::requestNextFrame(liveVizRequestMsg *lvmsg) {
+  // These specify the desired total image size requested by the client viewer
+  int wdes = lvmsg->req.wid;
+  int hdes = lvmsg->req.ht;
+   
+  int myWidthPx = wdes / m;
+  int myHeightPx = hdes / n;
+  int sx=thisIndex.x*myWidthPx;
+  int sy=thisIndex.y*myHeightPx; 
+
+  // set the output pixel values for rectangle
+  // Each component is a char which can have 256 possible values
+  unsigned char *intensity= new unsigned char[3*myWidthPx*myHeightPx];
+  for(int i=0;i<myHeightPx;++i) {
+    for(int j=0;j<myWidthPx;++j) {
+      // black background
+      color_pixel(intensity,myWidthPx,myHeightPx,j,i,0,0,0);
+    } 
+  }
+
+  for (int i=0; i < particles.length(); i++ ) {
+    int xpos = (int)((particles[i].x /(double) (L*m)) * wdes) - sx;
+    int ypos = (int)((particles[i].y /(double) (L*n)) * hdes) - sy;
+
+    Color c(particles[i].id);
+    color_pixel(intensity,myWidthPx,myHeightPx,xpos+1,ypos,c.R,c.B,c.G);
+    color_pixel(intensity,myWidthPx,myHeightPx,xpos-1,ypos,c.R,c.B,c.G);
+    color_pixel(intensity,myWidthPx,myHeightPx,xpos,ypos+1,c.R,c.B,c.G);
+    color_pixel(intensity,myWidthPx,myHeightPx,xpos,ypos-1,c.R,c.B,c.G);
+    color_pixel(intensity,myWidthPx,myHeightPx,xpos,ypos,c.R,c.B,c.G);
+  }
+        
+  for(int i=0;i<myHeightPx;++i) {
+    for(int j=0;j<myWidthPx;++j) {
+      // Draw red lines
+      if(i==0 || j==0) {
+       color_pixel(intensity,myWidthPx,myHeightPx,j,i,128,0,0);
+      }
+    }
+  }
+        
+  liveVizDeposit(lvmsg, sx,sy, myWidthPx,myHeightPx, intensity, this, max_image_data);
+  delete[] intensity;
+
+}*/
+
+// Prints all particles 
+void Patch::print(){
+#ifdef PRINT
+  int i;
+  CkPrintf("*****************************************************\n");
+  CkPrintf("Patch (%d,%d)\n",thisIndex.x,thisIndex.y);
+
+  // CkPrintf("Part     x     y\n");
+  for(i=0; i < particles.length(); i++)
+    CkPrintf("Patch (%d,%d) %-5d %7.4f %7.4f \n", thisIndex.x, thisIndex.y, i,
+                                             particles[i].x, particles[i].y);
+  CkPrintf("*****************************************************\n");
+#endif
+}
+
+#include "Patch.def.h"
diff --git a/examples/charm++/Molecular2D/Patch.ci b/examples/charm++/Molecular2D/Patch.ci
new file mode 100644 (file)
index 0000000..74e7fa2
--- /dev/null
@@ -0,0 +1,32 @@
+mainmodule Patch {
+
+  readonly CProxy_Main mainProxy;  
+  readonly CProxy_Patch patchArray;
+  readonly CProxy_Compute computeArray;
+
+  readonly int numParts;       // total number of particles
+  readonly int m;              // total number of rows in the grid
+  readonly int n;              // total number of columns in the grid
+  readonly int L;
+  readonly double radius;      // maximum distance between two interacting particles
+  readonly int finalStepCount; // number of steps at which the cells should stop computation
+
+  mainchare Main {
+    entry Main(CkArgMsg* msg);
+    entry void checkIn();
+  };
+
+  array [2D] Patch {
+    entry Patch();
+    entry void start();
+    entry void updateForces(CkVec<Particle> particles);
+    entry void updateParticles(CkVec<Particle> updates);
+    // entry void requestNextFrame(liveVizRequestMsg *m);
+  };
+
+  array [4D] Compute {
+    entry Compute();
+    entry void interact(CkVec<Particle>, int i, int j);
+  };
+
+};
diff --git a/examples/charm++/Molecular2D/Patch.h b/examples/charm++/Molecular2D/Patch.h
new file mode 100644 (file)
index 0000000..e987bbb
--- /dev/null
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * $Source$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *****************************************************************************/
+
+/** \file Patch.h
+ *  Author: Abhinav S Bhatele
+ *  Date Created: July 1st, 2008
+ *
+ */
+
+
+#ifndef __PATCH_H__
+#define __PATCH_H__
+
+/** \class Main
+ *
+ */
+class Main : public CBase_Main {
+  private:
+    int checkInCount; // Count to terminate
+
+  public:
+    Main(CkArgMsg* msg);
+    Main(CkMigrateMessage* msg);
+
+    void checkIn();
+};
+
+/** \class Patch
+ *  Class representing a cell in the grid. 
+ *  We consider each cell as a square of LxL units
+ */
+class Patch : public CBase_Patch {
+  private:
+    CkVec<Particle> particles;
+    CkVec<Particle> incomingParticles;
+    int forceCount;            // to count the returns from interactions
+    int stepCount;             // to count the number of steps, and decide when to stop
+    int updateCount;
+    bool updateFlag;
+    bool incomingFlag;
+
+    void updateProperties();   // updates properties after receiving forces from computes
+    void checkNextStep();      // checks whether to continue with next step
+    void print();              // prints all its particles
+
+  public:
+    Patch();
+    Patch(CkMigrateMessage *msg);
+    ~Patch();
+
+    void start();
+    void updateParticles(CkVec<Particle>&);
+    void updateForces(CkVec<Particle>&);
+    void limitVelocity(Particle&);
+    Particle& wrapAround(Particle &);
+    // void requestNextFrame(liveVizRequestMsg *m);
+};
+
+#endif
diff --git a/examples/charm++/Molecular2D/common.h b/examples/charm++/Molecular2D/common.h
new file mode 100644 (file)
index 0000000..4138042
--- /dev/null
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * $Source$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *****************************************************************************/
+
+/** \file common.h
+ *  Author: Abhinav S Bhatele
+ *  Date Created: July 1st, 2008
+ *
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include "pup.h"
+
+#define DEFAULT_MASS 1
+#define DEFAULT_DELTA 0.005
+#define DEFAULT_PARTICLES 2000
+#define DEFAULT_M 5
+#define DEFAULT_N 5
+#define DEFAULT_L 1
+#define DEFAULT_RADIUS 5
+#define DEFAULT_FINALSTEPCOUNT 10
+#define MAX_VELOCITY 30.0
+
+// Class for keeping track of the properties for a particle
+class Particle{
+  public:
+    double mass;       // mass of the particle
+    double x;          // position in x axis
+    double y;          // position in y axis
+    double fx;         // total forces on x axis
+    double fy;         // total forces on y axis
+    double ax;         // acceleration on x axis
+    double ay;         // acceleration on y axis
+    double vx;         // velocity on x axis
+    double vy;         // velocity on y axis
+    int id;
+
+    // Default constructor
+    Particle() {
+      fx = fy = 0.0;
+    }
+
+    // Function for pupping properties
+    void pup(PUP::er &p) {
+      p | mass;
+      p | x;
+      p | y;
+      p | fx;
+      p | fy;
+      p | ax;
+      p | ay;
+      p | vx;
+      p | vy;
+      p | id;
+    }
+};
+
+class Color {
+  public:
+    unsigned char R, G, B;
+
+    // Generate a unique color for each index from 0 to total-1
+    Color(int index){
+      int total = 8;
+      if(index % total == 0) {
+       R = 255;
+       G = 100;
+       B = 100;
+      } else if(index % total == 1) {
+       R = 100;
+       G = 255;
+       B = 100;
+      } else if(index % total == 2) {
+       R = 100;
+       G = 100;
+       B = 255;
+      } else if(index % total == 3) {
+       R = 100;
+       G = 255;
+       255;
+      } else if(index % total == 4) {
+       R = 100;
+       G = 255;
+       B = 255;
+      } else if(index % total == 5) {
+       R = 255;
+       G = 255;
+       B = 100;
+      } else if(index % total == 6) {
+       R = 255;
+       G = 100;
+       B = 255;
+      } else {
+       R = 170;
+       G = 170;
+       B = 170;
+      }
+    }  
+};
+
+#endif