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