00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include <stdlib.h>
00010 #include <unistd.h>
00011 #include <stdio.h>
00012 #include <math.h>
00013 #include "charm++.h"
00014 #include "fem.h"
00015 
00016 #include "ckvector3d.h"
00017 #include "charm-api.h"
00018 #include "fem_mesh.h"
00019 #include "netfem.h"
00020 #include "refine.h"
00021 #include "femrefine.h"
00022 #include "pgm.h"
00023 
00024 
00025 
00026 const double matConst[4]={3.692e9,  1.292e9,  3.692e9,  1.200e9 };
00027 
00028 
00029 const double density=5.0*1000.0;
00030 
00031 const double thickness=0.0001;
00032 
00033 
00034 
00035 const double dt=1.0e-12;
00036 
00037 static void die(const char *str) {
00038   CkError("Fatal error: %s\n",str);
00039   CkExit();
00040 }
00041 
00043 void resize_nodes(void *data,int *len,int *max);
00044 void resize_elems(void *data,int *len,int *max);
00045 void resize_edges(void *data,int *len,int *max);
00046 
00047 #define NANCHECK 1 
00048 
00049 extern "C" void
00050 init(void)
00051 {
00052   CkPrintf("init started\n");
00053 
00054   const char *eleName="out.1024.ele";
00055   const char *nodeName="out.1024.node";
00056   const char *edgeName="out.1024.edge";
00057   int nPts=0; 
00058   vector2d *pts=0; 
00059 
00060   CkPrintf("Reading node coordinates from %s\n",nodeName);
00061   
00062   {
00063     char line[1024];
00064     FILE *f=fopen(nodeName,"r");
00065     if (f==NULL) die("Can't open node file!");
00066     fgets(line,1024,f);
00067     if (1!=sscanf(line,"%d",&nPts)) die("Can't read number of points!");
00068     pts=new vector2d[nPts];
00069     for (int i=0;i<nPts;i++) {
00070       int ptNo;
00071       if (NULL==fgets(line,1024,f)) die("Can't read node input line!");
00072       if (3!=sscanf(line,"%d%lf%lf",&ptNo,&pts[i].x,&pts[i].y)) 
00073     die("Can't parse node input line!");
00074       pts[i].y = 4.0*pts[i].y;
00075     }
00076     fclose(f);
00077   }
00078   CkPrintf("Passing node coords to framework\n");
00079   
00080   
00081   
00082   
00083   FEM_Register_entity(FEM_Mesh_default_write(),FEM_NODE,NULL,nPts,nPts,resize_nodes);
00084   for(int k=0;k<=4;k++){
00085     if(k != 0){
00086       vector2d *t = new vector2d[nPts];
00087       FEM_Register_array(FEM_Mesh_default_write(),FEM_NODE,FEM_DATA+k,t,FEM_DOUBLE,2);
00088     }else{
00089       FEM_Register_array(FEM_Mesh_default_write(),FEM_NODE,FEM_DATA+k,pts,FEM_DOUBLE,2);
00090     }
00091   }
00092   double *td = new double[nPts];
00093   FEM_Register_array(FEM_Mesh_default_write(),FEM_NODE,FEM_DATA+5,td,FEM_DOUBLE,1);
00094   int *validNodes = new int[nPts];
00095   for(int ii=0;ii<nPts;ii++){
00096     validNodes[ii]=1;
00097   }
00098   FEM_Register_array(FEM_Mesh_default_write(),FEM_NODE,FEM_VALID,validNodes,FEM_INT,1);
00099   
00100   int nEle=0;
00101   int *ele=NULL;
00102   CkPrintf("Reading elements from %s\n",eleName);
00103   
00104   {
00105     char line[1024];
00106     FILE *f=fopen(eleName,"r");
00107     if (f==NULL) die("Can't open element file!");
00108     fgets(line,1024,f);
00109     if (1!=sscanf(line,"%d",&nEle)) die("Can't read number of elements!");
00110     ele=new int[3*nEle];
00111     for (int i=0;i<nEle;i++) {
00112       int elNo;
00113       if (NULL==fgets(line,1024,f)) die("Can't read element input line!");
00114       if (4!=sscanf(line,"%d%d%d%d",&elNo,&ele[3*i+0],&ele[3*i+1],&ele[3*i+2])) 
00115     die("Can't parse element input line!");
00116       ele[3*i+0]--; 
00117       ele[3*i+1]--; 
00118       ele[3*i+2]--; 
00119     }
00120     fclose(f);
00121   }
00122   
00123   CkPrintf("Passing elements to framework\n");
00124   
00125   
00126   FEM_Register_entity(FEM_Mesh_default_write(),FEM_ELEM,NULL,nEle,nEle,resize_elems);
00127   FEM_Register_array(FEM_Mesh_default_write(),FEM_ELEM,FEM_CONN,ele,FEM_INDEX_0,3);
00128   
00129   for(int k=0;k<3;k++){
00130     void *t = new double[nEle];
00131     FEM_Register_array(FEM_Mesh_default_write(),FEM_ELEM,FEM_DATA+k,t,FEM_DOUBLE,1);
00132   }
00133   int *validElem = new int[nEle];
00134   for(int ii=0;ii<nEle;ii++){
00135     validElem[ii]=1;
00136   }
00137   FEM_Register_array(FEM_Mesh_default_write(),FEM_ELEM,FEM_VALID,validElem,FEM_INT,1);
00138   
00139   
00140   FEM_Add_ghost_layer(2,0); 
00141   
00142   const static int tri2edge[6]={0,1, 1,2, 2,0};
00143   FEM_Add_ghost_elem(0,3,tri2edge);
00144 
00145   
00146   int nEdge;
00147   int *edgeConn;
00148   int *edgeBoundary;
00149   int *validEdge;
00150   {
00151     char line[1024];
00152     FILE *f=fopen(edgeName,"r");
00153     if (f==NULL) die("Can't open edge file!");
00154     fgets(line,1024,f);
00155     if (1!=sscanf(line,"%d",&nEdge)) die("Can't read number of elements!");
00156     edgeConn = new int[2*nEdge];
00157     edgeBoundary = new int[nEdge];
00158     validEdge = new int[nEdge];
00159     for(int i=0;i<nEdge;i++){
00160       int edgeNo;
00161       if (NULL==fgets(line,1024,f)) die("Can't read edge input line!");
00162       if (4 != sscanf(line,"%d%d%d%d",&edgeNo,&edgeConn[i*2+0],&edgeConn[i*2+1],&edgeBoundary[i])){
00163     die("Can't parse edge input line!");
00164       }
00165       edgeConn[i*2+0]--;
00166       edgeConn[i*2+1]--;        
00167       validEdge[i] = 1;
00168     }
00169     fclose(f);
00170   }
00171   printf("Number of edges %d \n",nEdge);
00172   FEM_Register_entity(FEM_Mesh_default_write(),FEM_SPARSE,NULL,nEdge,nEdge,resize_edges);
00173   FEM_Register_array(FEM_Mesh_default_write(),FEM_SPARSE,FEM_CONN,edgeConn,FEM_INDEX_0,2);
00174   FEM_Register_array(FEM_Mesh_default_write(),FEM_SPARSE,FEM_BOUNDARY,edgeBoundary,FEM_INT,1);
00175   FEM_Register_array(FEM_Mesh_default_write(),FEM_SPARSE,FEM_VALID,validEdge,FEM_INT,1);
00176   CkPrintf("Finished with init\n");
00177 }
00178 
00179 struct myGlobals {
00180   int nnodes,maxnodes;
00181   int nelems,maxelems;
00182   int nedges,maxedges;
00183   int *conn; 
00184   vector2d *coord; 
00185   vector2d *R_net, *d, *v, *a; 
00186   double *m_i; 
00187   int m_i_fid; 
00188   int *validNode,*validElem;
00189   int *nodeBoundary; 
00190   double *S11, *S22, *S12; 
00191   int *edgeConn;
00192   int *edgeBoundary;
00193   int *validEdge;
00194 };
00195 
00196 void pup_myGlobals(pup_er p,myGlobals *g) 
00197 {
00198   FEM_Print("-------- called pup routine -------");
00199   pup_int(p,&g->nnodes);
00200   pup_int(p,&g->nelems);
00201   pup_int(p,&g->nedges);
00202   pup_int(p,&g->maxelems);
00203   pup_int(p,&g->maxnodes);
00204   pup_int(p,&g->maxedges);
00205 
00206   int nnodes=g->nnodes, nelems=g->nelems;
00207   if (pup_isUnpacking(p)) {
00208     g->coord=new vector2d[g->maxnodes];
00209     g->conn=new int[3*g->maxelems];
00210     g->R_net=new vector2d[g->maxnodes]; 
00211     g->d=new vector2d[g->maxnodes];
00212     g->v=new vector2d[g->maxnodes];
00213     g->a=new vector2d[g->maxnodes];
00214     g->m_i=new double[g->maxnodes];
00215     g->S11=new double[g->maxelems];
00216     g->S22=new double[g->maxelems];
00217     g->S12=new double[g->maxelems];
00218     g->validNode = new int[g->maxnodes];
00219     g->validElem = new int[g->maxelems];
00220     g->edgeConn = new int[2*g->maxedges];
00221     g->edgeBoundary = new int[g->maxedges];
00222     g->validEdge = new int[g->maxedges];
00223   }
00224   pup_doubles(p,(double *)g->coord,2*nnodes);
00225   pup_ints(p,(int *)g->conn,3*nelems);
00226   pup_doubles(p,(double *)g->R_net,2*nnodes);
00227   pup_doubles(p,(double *)g->d,2*nnodes);
00228   pup_doubles(p,(double *)g->v,2*nnodes);
00229   pup_doubles(p,(double *)g->a,2*nnodes);
00230   pup_doubles(p,(double *)g->m_i,nnodes);
00231   pup_doubles(p,(double *)g->S11,nelems);
00232   pup_doubles(p,(double *)g->S22,nelems);
00233   pup_doubles(p,(double *)g->S12,nelems);
00234   pup_ints(p,(int *)g->validNode,nnodes);
00235   pup_ints(p,(int *)g->validElem,nelems);
00236   pup_ints(p,(int *)g->edgeConn,2*g->nedges);
00237   pup_ints(p,(int *)g->edgeBoundary,g->nedges);
00238   pup_ints(p,(int *)g->validEdge,g->nedges);
00239 
00240   if (pup_isDeleting(p)) {
00241     delete[] g->coord;
00242     delete[] g->conn;
00243     delete[] g->R_net;
00244     delete[] g->d;
00245     delete[] g->v;
00246     delete[] g->a;
00247     delete[] g->m_i;
00248     delete[] g->S11;
00249     delete[] g->S22;
00250     delete[] g->S12;
00251     delete[] g->validNode;
00252     delete[] g->validElem;
00253     delete[] g->edgeConn;
00254     delete[] g->edgeBoundary;
00255     delete[] g->validEdge;
00256   }
00257 }
00258 
00259 
00260 double calcArea(myGlobals &g, int i)
00261 {
00262   int n1=g.conn[3*i+0];
00263   int n2=g.conn[3*i+1];
00264   int n3=g.conn[3*i+2];
00265   vector2d a=g.coord[n1];
00266   vector2d b=g.coord[n2];
00267   vector2d c=g.coord[n3];
00268   c-=a; b-=a;
00269   double area=0.5*(b.x*c.y-c.x*b.y);
00270   return area;
00271 }
00272 
00273 
00274 void checkTriangle(myGlobals &g, int i)
00275 {
00276   double area=calcArea(g,i);
00277   if (area<0) {
00278     CkError("Triangle %d of chunk %d is inverted! (area=%g)\n",
00279         i,FEM_My_partition(),area);
00280     CkAbort("Inverted triangle");
00281   }
00282   if (area<1.0e-15) {
00283     CkError("Triangle %d of chunk %d is a sliver!\n",i,FEM_My_partition());
00284     CkAbort("Sliver triangle");
00285   }
00286 }
00287 
00288 
00289 void CST_NL(const vector2d *coor,const int *lm,vector2d *R_net,
00290         const vector2d *d,const double *c,
00291         int numnp,int numel,
00292         double *S11o,double *S22o,double *S12o);
00293 
00294 
00295 void advanceNodes(const double dt,int nnodes,const vector2d *coord,
00296           vector2d *R_net,vector2d *a,vector2d *v,vector2d *d,
00297           const double *m_i,bool dampen)
00298 {
00299   const vector2d z(0,0);
00300   const double shearForce=1.0e-11/(dt*dt);
00301   bool someNaNs=false;
00302   int i;
00303   for (i=0;i<nnodes;i++) {
00304     vector2d R_n=R_net[i];
00305 #if NANCHECK
00306     if (((R_n.x-R_n.x)!=0)) {
00307       CkPrintf("R_net[%d]=NaN at (%.4f,%.4f)   ",i,coord[i].x,coord[i].y);
00308       CmiAbort("nan node");
00309       someNaNs=true;
00310     }
00311     if (fabs(d[i].x)>1.0) {
00312       CkPrintf("d[%d] %f large at (%.4f,%.4f)   ",i,d[i].x,coord[i].x,coord[i].y);
00313       someNaNs=true;
00314     }
00315 #endif
00316     R_net[i]=z;
00317     
00318     if (1) {
00319       if (coord[i].x<0.00001)
00320     R_n.y+=shearForce/m_i[i]; 
00321       if (coord[i].y>0.02-0.00001)
00322     R_n=z; 
00323     }
00324     
00325     vector2d aNew=R_n*m_i[i];
00326     v[i]+=(dt*0.5)*(aNew+a[i]);
00327     d[i]+=dt*v[i]+(dt*dt*0.5)*aNew;
00328     a[i]=aNew;   
00329     
00330   }
00331   if (dampen)
00332     for (i=0;i<nnodes;i++)
00333       v[i]*=0.9; 
00334   
00335   if (someNaNs) {
00336     CkPrintf("Nodes all NaN!\n");
00337     CkAbort("Node forces NaN!");
00338   }
00339 }
00340 
00341 
00342 void calcMasses(myGlobals &g) {
00343   int i;
00344   double *m_i=g.m_i;
00345   
00346   for (i=0;i<g.nnodes;i++) m_i[i]=0.0;
00347   
00348   for (i=0;i<g.nelems;i++) {
00349     if(g.validElem[i]){
00350       int n1=g.conn[3*i+0];
00351       int n2=g.conn[3*i+1];
00352       int n3=g.conn[3*i+2];
00353       double area=calcArea(g,i);
00354       
00355       double mass=0.333*density*(thickness*area);
00356       m_i[n1]+=mass;
00357       m_i[n2]+=mass;
00358       m_i[n3]+=mass;
00359     }
00360   }
00361   
00362   FEM_Update_field(g.m_i_fid,m_i);
00363   
00364   for (i=0;i<g.nnodes;i++) {
00365     double mass=m_i[i];
00366     if (mass<1.0e-10) m_i[i]=1.0; 
00367     else m_i[i]=1.0/mass;
00368   }
00369 }
00370 
00371 void init_myGlobal(myGlobals *g){
00372   g->coord = g->R_net = g->d = g->v = g->a = NULL;
00373   g->m_i = NULL;
00374   g->conn = NULL;
00375   g->S11 = g->S22 = g->S12 = NULL;
00376 }
00377 
00378 
00379 void resize_nodes(void *data,int *len,int *max){
00380   printf("[%d] resize nodes called len %d max %d\n",FEM_My_partition(),*len,*max);
00381   FEM_Register_entity(FEM_Mesh_default_read(),FEM_NODE,data,*len,*max,resize_nodes);
00382   myGlobals *g = (myGlobals *)data;
00383   vector2d *coord=g->coord,*R_net=g->R_net,*d=g->d,*v=g->v,*a=g->a;
00384   double *m_i=g->m_i;
00385   int *bound = g->nodeBoundary;
00386   int *validNode = g->validNode;
00387   
00388   g->coord=new vector2d[*max];
00389   g->coord[0].x = 0.9;
00390   g->coord[0].y = 0.8;
00391   g->maxnodes = *max;
00392   g->R_net=new vector2d[g->maxnodes]; 
00393   g->d=new vector2d[g->maxnodes];
00394   g->v=new vector2d[g->maxnodes];
00395   g->a=new vector2d[g->maxnodes];
00396   g->m_i=new double[g->maxnodes];
00397   g->nodeBoundary = new int[(*max)];
00398   g->validNode = new int[g->maxnodes]; 
00399   
00400   if(coord != NULL){
00401     for(int k=0;k<*len;k++){
00402       printf("before resize node %d ( %.6f %.6f ) \n",k,coord[k].x,coord[k].y);
00403     }
00404   } 
00405   
00406   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA,(void *)g->coord,FEM_DOUBLE,2);
00407   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA+1,(void *)g->R_net,FEM_DOUBLE,2);
00408   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA+2,(void *)g->d,FEM_DOUBLE,2);
00409   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA+3,(void *)g->v,FEM_DOUBLE,2);
00410   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA+4,(void *)g->a,FEM_DOUBLE,2);
00411   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_BOUNDARY,(void *)g->nodeBoundary,FEM_INT,1);
00412   FEM_Register_array_layout(FEM_Mesh_default_read(),FEM_NODE,FEM_DATA+5,(void *)g->m_i,g->m_i_fid);
00413   FEM_Register_array(FEM_Mesh_default_read(),FEM_NODE,FEM_VALID,(void *)g->validNode,FEM_INT,1);
00414   
00415   for(int k=0;k<*len;k++){
00416     printf("after resize node %d ( %.6f %.6f )\n",k,g->coord[k].x,g->coord[k].y);
00417   }
00418   
00419   if(coord != NULL){
00420     delete [] coord;
00421     delete [] R_net;
00422     delete [] d;
00423     delete [] v;
00424     delete [] a;
00425     delete [] m_i;
00426     delete [] bound;
00427     delete [] validNode;
00428   }
00429 };
00430 
00431 void resize_elems(void *data,int *len,int *max){
00432   printf("[%d] resize elems called len %d max %d\n",FEM_My_partition(),*len,*max);
00433   FEM_Register_entity(FEM_Mesh_default_read(),FEM_ELEM,data,*len,*max,resize_elems);
00434   myGlobals *g = (myGlobals *)data;
00435   int *conn=g->conn;
00436   double *S11 = g->S11,*S22 = g->S22,*S12 = g->S12;
00437   int *validElem = g->validElem;
00438   
00439   g->conn = new int[3*(*max)];
00440   g->maxelems = *max;
00441   g->S11=new double[g->maxelems];
00442   g->S22=new double[g->maxelems];
00443   g->S12=new double[g->maxelems];
00444   g->validElem = new int[g->maxelems];
00445   
00446   FEM_Register_array(FEM_Mesh_default_read(),FEM_ELEM,FEM_CONN,(void *)g->conn,FEM_INDEX_0,3);  
00447   CkPrintf("Connectivity array starts at %p \n",g->conn);
00448   FEM_Register_array(FEM_Mesh_default_read(),FEM_ELEM,FEM_DATA,(void *)g->S11,FEM_DOUBLE,1);    
00449   FEM_Register_array(FEM_Mesh_default_read(),FEM_ELEM,FEM_DATA+1,(void *)g->S22,FEM_DOUBLE,1);  
00450   FEM_Register_array(FEM_Mesh_default_read(),FEM_ELEM,FEM_DATA+2,(void *)g->S12,FEM_DOUBLE,1);  
00451   FEM_Register_array(FEM_Mesh_default_read(),FEM_ELEM,FEM_VALID,(void *)g->validElem,FEM_INT,1);    
00452   
00453   if(conn != NULL){
00454     delete [] conn;
00455     delete [] S11;
00456     delete [] S22;
00457     delete [] S12;
00458     delete [] validElem;
00459   }
00460 };
00461 
00462 void resize_edges(void *data,int *len,int *max){
00463   printf("[%d] resize edges called len %d max %d\n",FEM_My_partition(),*len,*max);
00464   FEM_Register_entity(FEM_Mesh_default_read(),FEM_SPARSE,data,*len,*max,resize_edges);
00465   myGlobals *g = (myGlobals *)data;
00466   
00467   int *conn = g->edgeConn;
00468   int *bound = g->edgeBoundary;
00469   int *validEdge = g->validEdge;
00470   g->maxedges = *max;   
00471   g->edgeConn = new int[2*(*max)];
00472   g->edgeBoundary = new int[(*max)];
00473   g->validEdge = new int[(*max)];
00474   
00475   FEM_Register_array(FEM_Mesh_default_read(),FEM_SPARSE,FEM_CONN,(void *)g->edgeConn,FEM_INDEX_0,2);    
00476   FEM_Register_array(FEM_Mesh_default_read(),FEM_SPARSE,FEM_BOUNDARY,(void *)g->edgeBoundary,FEM_INT,1);
00477   FEM_Register_array(FEM_Mesh_default_read(),FEM_SPARSE,FEM_VALID,(void *)g->validEdge,FEM_INT,1);
00478   if(conn != NULL){
00479     delete [] conn;
00480     delete [] bound;    
00481     delete [] validEdge;
00482   }
00483 }
00484 
00485 void repeat_after_split(void *data){
00486   myGlobals *g = (myGlobals *)data;
00487   g->nelems = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_ELEM);
00488   g->nnodes = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_NODE);
00489   for(int k=0;k<g->nnodes;k++){
00490     if(g->validNode[k]){
00491       printf(" node %d ( %.6f %.6f )\n",k,g->coord[k].x,g->coord[k].y);
00492     }   
00493   }
00494   calcMasses(*g);
00495 };
00496 
00497 
00498 void publishMeshToNetFEM(myGlobals &g,int myChunk,int t);
00499 int countValidEntities(int *validData,int total);
00500 
00501 
00502 extern "C" void
00503 driver(void)
00504 {
00505   int i;  
00506   int myChunk=FEM_My_partition();
00507   
00508   
00509   CkPrintf("[%d] begin init\n",myChunk);
00510   FEM_REFINE2D_Init();
00511   CkPrintf("[%d] end init\n",myChunk);
00512   
00513   myGlobals g;
00514   FEM_Register(&g,(FEM_PupFn)pup_myGlobals);
00515   init_myGlobal(&g);
00516   
00517   g.nnodes = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_NODE);
00518   int maxNodes = g.nnodes;
00519   g.maxnodes=2*maxNodes;
00520   g.m_i_fid=FEM_Create_field(FEM_DOUBLE,1,0,sizeof(double));
00521   resize_nodes((void *)&g,&g.nnodes,&maxNodes);
00522   int nghost=0;
00523   g.nelems=FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_ELEM);
00524   g.maxelems=g.nelems;
00525   resize_elems((void *)&g,&g.nelems,&g.maxelems);
00526 
00527   FEM_REFINE2D_Newmesh(FEM_Mesh_default_read(),FEM_NODE,FEM_ELEM);
00528   
00529   
00530   for (i=0;i<g.maxnodes;i++) {
00531     g.R_net[i]=g.d[i]=g.v[i]=g.a[i]=vector2d(0.0);
00532   }
00533   
00534   
00535   
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543   int fid=FEM_Create_field(FEM_DOUBLE,2,0,sizeof(vector2d));
00544   for (i=0;i<g.nelems;i++){
00545     checkTriangle(g,i);
00546   } 
00547 
00548   calcMasses(g);
00549   double startTime=CkWallTimer();
00550 
00551   
00552   publishMeshToNetFEM(g,myChunk,0);
00553 
00554   double avgArea = 0.0;
00555   for (i=0;i<g.nelems;i++) avgArea += calcArea(g, i);
00556   avgArea /= g.nelems;
00557 
00558   if (CkMyPe()==0) CkPrintf("Entering timeloop\n");
00559   int tSteps=10;
00560   int k=2;
00561   for (int t=1;t<=tSteps;t++) {
00562     double curTime=CkWallTimer();
00563     double total=curTime-startTime;
00564     startTime=curTime;
00565     vector2d *loc;
00566     double *areas;
00567     
00568     
00569     loc=new vector2d[2*g.nnodes];
00570     for (i=0;i<g.nnodes;i++) {
00571       loc[i]=g.coord[i];
00572     }
00573     areas=new double[g.nelems];
00574     for (i=0;i<g.nelems;i++) {
00575       areas[i] = avgArea;
00576     }
00577     CkPrintf("[%d] Starting coarsening step: %d nodes, %d elements\n", myChunk,countValidEntities(g.validNode,g.nnodes),countValidEntities(g.validElem,g.nelems));
00578     FEM_REFINE2D_Coarsen(FEM_Mesh_default_read(),FEM_NODE,(double *)g.coord,FEM_ELEM,areas,FEM_SPARSE);
00579     repeat_after_split((void *)&g);
00580     g.nelems = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_ELEM);
00581     g.nnodes = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_NODE);
00582     CkPrintf("[%d] Done with coarsening step: %d nodes, %d elements\n",
00583          myChunk,countValidEntities(g.validNode,g.nnodes),countValidEntities(g.validElem,g.nelems));
00584     delete[] loc;
00585     delete[] areas;
00586     
00587     publishMeshToNetFEM(g,myChunk,2*t-1);
00588 
00589     
00590     loc=new vector2d[2*g.nnodes];
00591     for (i=0;i<g.nnodes;i++) {
00592       loc[i]=g.coord[i];
00593     }
00594     areas=new double[g.nelems];
00595     for (i=0;i<g.nelems;i++) {
00596       areas[i] = avgArea;
00597       
00598     }
00599 
00600     CkPrintf("[%d] Starting refinement step: %d nodes, %d elements\n", myChunk,countValidEntities(g.validNode,g.nnodes),countValidEntities(g.validElem,g.nelems));
00601     FEM_REFINE2D_Split(FEM_Mesh_default_read(),FEM_NODE,(double *)loc,FEM_ELEM,areas,FEM_SPARSE);
00602     repeat_after_split((void *)&g);
00603     
00604     g.nelems = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_ELEM);
00605     g.nnodes = FEM_Mesh_get_length(FEM_Mesh_default_read(),FEM_NODE);
00606     CkPrintf("[%d] Done with refinement step: %d nodes, %d elements\n",
00607          myChunk,countValidEntities(g.validNode,g.nnodes),countValidEntities(g.validElem,g.nelems));
00608     delete[] loc;
00609     delete[] areas;
00610     
00611     publishMeshToNetFEM(g,myChunk,2*t);
00612   }
00613   if (CkMyPe()==0) CkPrintf("Driver finished\n");
00614 }
00615 
00616 int countValidEntities(int *validData,int total)
00617 {
00618   int sum =0 ;
00619   for(int i=0;i<total;i++){
00620     sum += validData[i];
00621   }
00622   return sum;
00623 }
00624 
00625 
00626 void publishMeshToNetFEM(myGlobals &g,int myChunk,int t)
00627 {
00628   NetFEM n=NetFEM_Begin(myChunk,t,2,NetFEM_WRITE);
00629   int count=0;
00630   double *vcoord = new double[2*g.nnodes];
00631   double *vnodeid = new double[g.nnodes];
00632   int *maptovalid = new int[g.nnodes];
00633   for(int i=0;i<g.nnodes;i++){
00634     if(g.validNode[i]){
00635       vcoord[2*count] = ((double *)g.coord)[2*i];
00636       vcoord[2*count+1] = ((double *)g.coord)[2*i+1];
00637       maptovalid[i] = count;
00638       printf("~~~~~~~ %d %d %.6lf %.6lf \n",count,i,vcoord[2*count],vcoord[2*count+1]);
00639       vnodeid[count] = i;
00640       count++;  
00641     }
00642   }
00643   NetFEM_Nodes(n,count,(double *)vcoord,"Position (m)");
00644   NetFEM_Scalar(n,vnodeid,1,"Node ID");
00645   
00646 
00647   count=0;
00648   int *vconn = new int[3*g.nelems];
00649   double *vid = new double[3*g.nelems];
00650   for(int i=0;i<g.nelems;i++){
00651     if(g.validElem[i]){
00652       vconn[3*count] = maptovalid[g.conn[3*i]];
00653       vconn[3*count+1] = maptovalid[g.conn[3*i+1]];
00654       vconn[3*count+2] = maptovalid[g.conn[3*i+2]];
00655       printf("~~~~~~~ %d %d < %d,%d %d,%d %d,%d >\n",count,i,vconn[3*count],g.conn[3*i],vconn[3*count+1],g.conn[3*i+1],vconn[3*count+2],g.conn[3*i+2]);
00656       vid[count]=count;
00657       count++;  
00658     }
00659   }
00660   NetFEM_Elements(n,count,3,(int *)vconn,"Triangles");
00661   NetFEM_Scalar(n,vid,1,"Element ID");
00662   
00663 
00664   NetFEM_End(n);
00665   delete [] vcoord;
00666   delete [] vconn;
00667   delete [] maptovalid;
00668   delete [] vid;
00669   delete [] vnodeid;
00670 }