00001 
00002 
00003 
00004 
00005 
00006 #ifndef __OSL_NETFEM_DATA_H
00007 #define __OSL_NETFEM_DATA_H
00008 
00009 #include "charm++.h"
00010 #include "pup.h"
00011 
00012     class CkShortStr {
00013         enum {maxLen=32};
00014         char store[maxLen];
00015         void terminate(void) {
00016             store[maxLen-1]=0;
00017         }
00018     public:
00019         CkShortStr() {} 
00020         CkShortStr(const char *s) {copyFrom(s);}
00021         CkShortStr(const char *s,int l) {copyFrom(s,l);}
00022         
00023         void operator=(const char *s) { copyFrom(s);}
00024         void copyFrom(const char *s) {copyFrom(s,strlen(s));}
00025         void copyFrom(const char *s,int len);
00026         operator const char *() const {return store;}
00027         
00028         void pup(PUP::er &p) {
00029             int len=strlen(store)+1;
00030             p(len);
00031             p(store,len);
00032             terminate();
00033         }
00034     };
00035 
00036 template <class T>
00037 inline T *CkShiftPointer(T *p,int bytesToShift) {
00038     return (T *)(bytesToShift+(char *)p);
00039 }
00040 
00041 
00042 class NetFEM_format {
00043 public:
00044     int vec_len;
00045     int distance;
00046     NetFEM_format() {}
00047     NetFEM_format(int len) 
00048         :vec_len(len), distance(len*sizeof(double))
00049         {}
00050     NetFEM_format(int len,int dist)
00051         :vec_len(len), distance(dist) 
00052         {}
00053     
00054     
00055     double *forItem(double *start,int item) const {
00056         char *s=(char *)start;
00057         return (double *)(s+item*distance);
00058     }
00059     const double *forItem(const double *start,int item) const {
00060         return forItem((double *)start,item);
00061     }
00062         
00063     
00064     int nDoubles(void) const {return vec_len;}
00065 };
00066 
00067 
00068 class NetFEM_doubleField {
00069     friend class NetFEM_item; 
00070     int n; 
00071     double *start;
00072     NetFEM_format fmt; 
00073     bool isSpatial;
00074     CkShortStr name;
00075     bool isHeapAllocated;
00076         
00077     void allocate(void) {
00078         start=new double[n*fmt.vec_len];
00079         isHeapAllocated=true;
00080     }
00081 public:
00082     NetFEM_doubleField() {
00083         isHeapAllocated=false;
00084     }
00085     ~NetFEM_doubleField() {
00086         if (isHeapAllocated) {
00087             delete[] start;
00088         }
00089     }
00090 
00091     const char *getName(void) const {return name;}
00092     bool getSpatial(void) const {return isSpatial;}
00093     int getItems(void) const {return n;}
00094     int getDoublesPerItem(void) const {return fmt.vec_len;}
00095     int getStride(void) const {return fmt.vec_len;}
00096     const double *getData(int itemNo) const {return fmt.forItem(start,itemNo);}
00097     
00098     void pup(PUP::er &p);
00099     
00100     
00101     void copy(void);
00102 };
00103 
00104 
00105 class NetFEM_item {
00106 private:
00107     int n; 
00108     enum {maxFields=8};
00109     NetFEM_doubleField fields[maxFields];
00110     int nFields;
00111 public:
00112     NetFEM_item() {
00113         n=0;
00114         nFields=0;
00115     }
00116     NetFEM_item(int nItems) {
00117         n=nItems;
00118         nFields=0;
00119     }
00120 
00121     virtual ~NetFEM_item();
00122 
00123     int getItems(void) const {return n;}
00124     int getFields(void) const {return nFields;}
00125     const NetFEM_doubleField &getField(int fieldNo) const 
00126         {return fields[fieldNo];}
00127 
00128     void add(double *start,const NetFEM_format &fmt,
00129         const char *name, bool isSpatialVector);
00130     virtual void copy(void); 
00131     virtual void pup(PUP::er &p);
00132 };
00133 
00134 class NetFEM_nodes : public NetFEM_item {
00135 public:
00136     NetFEM_nodes() {}
00137 
00138     const NetFEM_doubleField &getCoord(void) const {return getField(0);}
00139 
00140     NetFEM_nodes(int nNode,const NetFEM_format &fmt,double *coord,const char *name) 
00141         :NetFEM_item(nNode)
00142     {
00143         
00144         add(coord,fmt,name,true);
00145     }
00146 };
00147 
00148 
00149 class NetFEM_elems : public NetFEM_item {
00150     typedef NetFEM_item super;
00151 
00152 
00153     CkShortStr name; 
00154     int nodesPer,bytesPer,idxBase;
00155     int *conn;
00156     bool isHeapAllocated; 
00157 
00158     void allocate(void) {
00159         isHeapAllocated=true;
00160         conn=new int[getItems()*nodesPer];
00161     }
00162     void localCopy(void);
00163 public:
00164     NetFEM_elems() {
00165         nodesPer=0;
00166         bytesPer=0;
00167         idxBase=0;
00168         conn=NULL;
00169         isHeapAllocated=false;
00170     }
00171 
00172     NetFEM_elems(int nEl,int nodesPerEl,int bytesPerEl,
00173             int idxBase_,int *conn_,const char *name_) 
00174         :super(nEl),nodesPer(nodesPerEl),bytesPer(bytesPerEl),idxBase(idxBase_),
00175          conn(conn_),isHeapAllocated(false)
00176     {
00177         name=name_;
00178     }
00179     ~NetFEM_elems() {
00180         if (isHeapAllocated) delete[] conn;
00181     }
00182     int getNodesPer(void) const {return nodesPer;}
00183     const int *getNodes(int elementNo) const {return &conn[elementNo*nodesPer];}
00184     const char *getName(void) const {return name;}
00185 
00186     
00187     
00188     
00189     int getConnData(int elementNo, int dimension) const {return conn[elementNo*bytesPer/sizeof(int)+dimension];}
00190     int getConnWidth() const {return bytesPer/sizeof(int);}
00191 
00192     virtual void copy(void);
00193     virtual void pup(PUP::er &p);
00194 };
00195 
00196 
00197 
00198 class NetFEM_update {
00199     int source,timestep,dim;
00200 
00201     NetFEM_nodes *nodes;
00202     enum {maxElems=20};
00203     NetFEM_elems *elems[maxElems];
00204     int nElems;
00205     NetFEM_item *cur;
00206 public:
00207     NetFEM_update(int src_,int ts,int dim_)
00208         :source(src_),timestep(ts),dim(dim_)
00209     {
00210         nodes=NULL;
00211         for (int i=0;i<maxElems;i++) elems[i]=NULL;
00212         nElems=0;
00213         cur=NULL;
00214     }
00215     ~NetFEM_update() {
00216         delete nodes;
00217         for (int i=0;i<nElems;i++)
00218             delete elems[i];
00219     }
00220     int getSource(void) const {return source;}
00221     int getTimestep(void) const {return timestep;}
00222     int getDim(void) const {return dim;}
00223     int getElems(void) const {return nElems;}
00224     const NetFEM_nodes &getNodes(void) const {return *nodes;}
00225     const NetFEM_elems &getElem(int i) const {return *elems[i];}
00226 
00227     void addNodes(NetFEM_nodes *n);
00228     void addElems(NetFEM_elems *n);
00229 
00230     NetFEM_item *getItem(void);
00231     void pup(PUP::er &p);
00232 };
00233 
00236 void *pack(NetFEM_update &u,int *len);
00237 void unpack(NetFEM_update &u,const void *buf,int bufLen);
00238 
00239 #endif
00240