00001
00002
00003
00004
00005 #include "charm++.h"
00006 #include "netfem.h"
00007 #include "netfem.decl.h"
00008 #include "charm-api.h"
00009 #include "pup_toNetwork4.h"
00010 #include "conv-ccs.h"
00011 #include <string.h>
00012
00013 #include "netfem_data.h"
00014
00015 #include "pup_toNetwork4.h"
00016
00017 #include "tcharm.h"
00018 #define NETFEMAPI(routineName) TCHARM_API_TRACE(routineName,"netfem")
00019
00020
00021 class NetFEM_flavor {
00022 public:
00023 int flavor;
00024 bool doCopy;
00025 bool doWrite;
00026 NetFEM_flavor(int flavor_)
00027 :flavor(flavor_)
00028 {
00029 doCopy=(flavor>=NetFEM_COPY);
00030 doWrite=(flavor==NetFEM_WRITE);
00031 }
00032 };
00033
00034
00035 class NetFEM_updatePackage : public NetFEM_update {
00036 NetFEM_flavor flavor;
00037 public:
00038 NetFEM_updatePackage(int src_,int ts_,int dim_,int flavor_)
00039 :NetFEM_update(src_,ts_,dim_),flavor(flavor_) {}
00040
00041 const NetFEM_flavor &getFlavor(void) const {return flavor;}
00042
00045 void *pupMallocBuf(int *len) {
00046
00047 int respLen;
00048 {PUP_toNetwork4_sizer p; pup(p); respLen=p.size();}
00049
00050 void *respBuf=malloc(respLen);
00051 {PUP_toNetwork4_pack p(respBuf); pup(p); }
00052 *len=respLen;
00053 return respBuf;
00054 }
00055 };
00056
00057
00058
00059 class NetFEM_state {
00060
00061
00062
00063
00064
00065
00066 NetFEM_updatePackage *cur;
00067 public:
00068 NetFEM_state() {cur=NULL;}
00069 ~NetFEM_state() {
00070 delete cur;
00071 }
00072 void add(NetFEM_updatePackage *u)
00073 {
00074 delete cur;
00075 cur=u;
00076 }
00077
00078 void getCurrent(char *request,CcsDelayedReply reply)
00079 {
00080
00081 int respLen = 0;
00082 void *respBuf=cur?cur->pupMallocBuf(&respLen):NULL;
00083
00084 CcsSendDelayedReply(reply,respLen,respBuf);
00085 if (respBuf != NULL) free(respBuf);
00086 }
00087 NetFEM_update *stateForStep(int stepNo) {
00088
00089 return cur;
00090 }
00091 };
00092
00093 CpvDeclare(NetFEM_state *,netfem_state);
00094
00095 static NetFEM_state *getState(void) {
00096 NetFEM_state *ret=CpvAccess(netfem_state);
00097 if (ret==NULL) {
00098 ret=new NetFEM_state;
00099 CpvAccess(netfem_state)=ret;
00100 }
00101 return ret;
00102 }
00103
00104 extern "C" void NetFEM_getCurrent(void *request)
00105 {
00106 CcsDelayedReply reply=CcsDelayReply();
00107 char *reqPtr=(char *)request;
00108 reqPtr+=CmiMsgHeaderSizeBytes;
00109 getState()->getCurrent(reqPtr,reply);
00110 CmiFree(request);
00111 }
00112
00113
00114 void NetFEM_Init(void)
00115 {
00116 CpvInitialize(NetFEM_state *,netfem_state);
00117 CpvAccess(netfem_state) = NULL;
00118 CcsRegisterHandler("NetFEM_current",(CmiHandler)NetFEM_getCurrent);
00119 }
00120
00121 #define FTN_STR_DECL const char *strData,int strLen
00122 #define FTN_STR makeCString(strData,strLen)
00123 static CkShortStr makeCString(const char *data,int len)
00124 {
00125 if (len>32 || len<0)
00126 CkAbort("F90 string has suspicious length-- is NetFEM ignorant of how your f90 compiler passes strings?");
00127 return CkShortStr(data,len);
00128 }
00129 typedef int *NetFEMF;
00130 #define N ((NetFEM_updatePackage *)n)
00131 #define NF ((NetFEM_updatePackage *)*nf)
00132
00133
00134
00135 CLINKAGE NetFEM NetFEM_Begin(
00136 int source,
00137 int timestep,
00138 int dim,
00139 int flavor
00140 )
00141 {
00142 NETFEMAPI("NetFEM_Begin");
00143
00144 if (CkNumPes()==1) CthYield();
00145
00146 return (NetFEM)(new NetFEM_updatePackage(source,timestep,dim,flavor));
00147 }
00148 FLINKAGE NetFEMF FTN_NAME(NETFEM_BEGIN,netfem_begin)(int *s,int *t,int *d,int *f)
00149 {
00150 return (NetFEMF)NetFEM_Begin(*s,*t,*d,*f);
00151 }
00152
00153 CLINKAGE void NetFEM_End(NetFEM n) {
00154 NETFEMAPI("NetFEM_End");
00155 if (N->getFlavor().doWrite)
00156 {
00157 char dirName[256], fName[256];
00158 const char *baseDir="NetFEM";
00159 CmiMkdir(baseDir);
00160 sprintf(dirName,"%s/%d",baseDir,N->getTimestep());
00161 CmiMkdir(dirName);
00162 sprintf(fName,"%s/%d.dat",dirName,N->getSource());
00163 FILE *f=fopen(fName,"wb");
00164 if (f!=NULL) {
00165 int respLen;
00166 void *respBuf=N->pupMallocBuf(&respLen);
00167 if (respLen!=(int)fwrite(respBuf,1,respLen,f))
00168 CkAbort("Error writing NetFEM output file!");
00169 free(respBuf);
00170 fclose(f);
00171 }
00172 else {
00173 CkError("ERROR> Can't create NetFEM output file %s!\n",fName);
00174 CkAbort("Can't create NetFEM output file!");
00175 }
00176 }
00177 getState()->add(N);
00178 }
00179 FLINKAGE void FTN_NAME(NETFEM_END,netfem_end)(NetFEMF nf) {
00180 NetFEM_End((NetFEM)NF);
00181 }
00182
00183
00184
00185
00186
00187
00188 CLINKAGE void NetFEM_Nodes_field(NetFEM n,int nNodes,
00189 int init_offset,int distance,
00190 const void *loc,const char *name)
00191 {
00192 NETFEMAPI("NetFEM_Nodes");
00193 int d=N->getDim();
00194 N->addNodes(new NetFEM_nodes(nNodes,NetFEM_format(d,distance),
00195 CkShiftPointer((double *)loc,init_offset),name));
00196 }
00197
00198 FLINKAGE void FTN_NAME(NETFEM_NODES_FIELD,netfem_nodes_field)
00199 (NetFEMF nf,int *nNodes,int *off,int *dist,const void *loc,FTN_STR_DECL)
00200 {
00201 CkShortStr s=FTN_STR;
00202 NetFEM_Nodes_field((NetFEM)NF,*nNodes,*off,*dist,loc,s);
00203 }
00204
00205 CLINKAGE void NetFEM_Nodes(NetFEM n,int nNodes,const double *loc,const char *name) {
00206 NetFEM_Nodes_field(n,nNodes,0,N->getDim()*sizeof(double),loc,name);
00207 }
00208
00209 FLINKAGE void FTN_NAME(NETFEM_NODES,netfem_nodes)
00210 (NetFEMF nf,int *nNodes,const double *loc,FTN_STR_DECL)
00211 {
00212 CkShortStr s=FTN_STR;
00213 NetFEM_Nodes((NetFEM)NF,*nNodes,loc,s);
00214 }
00215
00216
00217
00218
00219
00220 CLINKAGE void NetFEM_Elements_field(NetFEM n,int nEl,int nodePerEl,
00221 int initOffset,int bytePerEl,int idxBase,
00222 const void *conn,const char *name)
00223 {
00224 NETFEMAPI("NetFEM_Elements_field");
00225 N->addElems(new NetFEM_elems(nEl,nodePerEl,bytePerEl,
00226 idxBase,CkShiftPointer((int *)conn,initOffset),name));
00227 }
00228
00229 FLINKAGE void FTN_NAME(NETFEM_ELEMENTS_FIELD,netfem_elements_field)
00230 (NetFEMF nf,int *nEl,int *nodePer,
00231 int *initOff,int *bytePer,int *idxBase,
00232 const void *conn,FTN_STR_DECL)
00233 {
00234 CkShortStr s=FTN_STR;
00235 NetFEM_Elements_field((NetFEM)NF,*nEl,*nodePer,*initOff,*bytePer,*idxBase,conn,s);
00236 }
00237
00238 CLINKAGE void NetFEM_Elements(NetFEM n,int nEl,int nodePerEl,const int *conn,const char *name)
00239 {
00240 NetFEM_Elements_field(n,nEl,nodePerEl,0,sizeof(int)*nodePerEl,0,conn,name);
00241 }
00242
00243 FLINKAGE void FTN_NAME(NETFEM_ELEMENTS,netfem_elements)
00244 (NetFEMF nf,int *nEl,int *nodePerEl,const int *conn,FTN_STR_DECL)
00245 {
00246 CkShortStr s=FTN_STR;
00247 NetFEM_Elements_field((NetFEM)NF,*nEl,*nodePerEl,0,sizeof(int)* *nodePerEl,1,conn,s);
00248 }
00249
00250
00251
00252
00253
00254
00255
00256 CLINKAGE void NetFEM_Vector_field(NetFEM n,const void *start,
00257 int init_offset,int distance,
00258 const char *name)
00259 {
00260 NETFEMAPI("NetFEM_Vector_field");
00261 NetFEM_format fmt(N->getDim(),distance);
00262 N->getItem()->add(CkShiftPointer((double *)start,init_offset),fmt,name,true);
00263 }
00264 FLINKAGE void FTN_NAME(NETFEM_VECTOR_FIELD,netfem_vector_field)
00265 (NetFEMF nf,const double *start,int *init_offset,int *distance,FTN_STR_DECL)
00266 {
00267 NETFEMAPI("NetFEM_vector_field");
00268 CkShortStr s=FTN_STR;
00269 NetFEM_Vector_field((NetFEM)NF,start,*init_offset,*distance,s);
00270 }
00271
00272
00273
00274
00275 CLINKAGE void NetFEM_Vector(NetFEM n,const double *data,const char *name)
00276 {
00277 NetFEM_Vector_field(n,data,0,sizeof(double)*N->getDim(),name);
00278 }
00279 FLINKAGE void FTN_NAME(NETFEM_VECTOR,netfem_vector)
00280 (NetFEMF nf,const double *data,FTN_STR_DECL)
00281 {
00282 CkShortStr s=FTN_STR;
00283 NetFEM_Vector((NetFEM)NF,data,s);
00284 }
00285
00286
00287
00288
00289
00290 CLINKAGE void NetFEM_Scalar_field(NetFEM n,const void *start,
00291 int vec_len,int init_offset,int distance,
00292 const char *name)
00293 {
00294 NETFEMAPI("NetFEM_Scalar_field");
00295 NetFEM_format fmt(vec_len,distance);
00296 N->getItem()->add(CkShiftPointer((double *)start,init_offset),fmt,name,false);
00297 }
00298
00299 FLINKAGE void FTN_NAME(NETFEM_SCALAR_FIELD,netfem_scalar_field)
00300 (NetFEMF nf,const double *start,int *veclen,int *init_offset,
00301 int *distance,FTN_STR_DECL)
00302 {
00303 NETFEMAPI("NetFEM_scalar_field");
00304 CkShortStr s=FTN_STR;
00305 NetFEM_Scalar_field((NetFEM)NF,start,*veclen,*init_offset,*distance,s);
00306 }
00307
00308
00309
00310 CLINKAGE void NetFEM_Scalar(NetFEM n,const double *start,int doublePer,
00311 const char *name)
00312 {
00313 NetFEM_Scalar_field(n,start,doublePer,0,sizeof(double)*doublePer,name);
00314 }
00315 FLINKAGE void FTN_NAME(NETFEM_SCALAR,netfem_scalar)
00316 (NetFEMF nf,const double *start,int *veclen,FTN_STR_DECL)
00317 {
00318 CkShortStr s=FTN_STR;
00319 NetFEM_Scalar((NetFEM)NF,start,*veclen,s);
00320 }
00321
00322
00323 #include "netfem.def.h"
00324