00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __CHARM_FEM_MESH_H
00011 #define __CHARM_FEM_MESH_H
00012
00013 #include "charm-api.h"
00014
00015 #ifndef __CHARM_IDXL_COMM_H
00016 # include "idxl_comm.h"
00017 #endif
00018 #ifndef __CHARM_IDXL_LAYOUT_H
00019 # include "idxl_layout.h"
00020 #endif
00021
00022 #if defined(_WIN32) && defined(max)
00023 #undef max
00024 #endif
00025
00026
00027 typedef IDXL_Side FEM_Comm;
00028 typedef IDXL_List FEM_Comm_List;
00029 typedef IDXL_Rec FEM_Comm_Rec;
00030 class IDXL_Chunk;
00031
00036 class FEM_Comm_Holder {
00037 IDXL comm;
00038 bool registered;
00039 IDXL_Comm_t idx;
00040 void registerIdx(IDXL_Chunk *c);
00041 public:
00042 FEM_Comm_Holder(FEM_Comm *sendComm, FEM_Comm *recvComm);
00043 void pup(PUP::er &p);
00044 ~FEM_Comm_Holder(void);
00045
00047 inline IDXL_Comm_t getIndex(IDXL_Chunk *c) {
00048 if (idx==-1) registerIdx(c);
00049 return idx;
00050 }
00051 };
00052
00053
00055
00056
00057
00061 typedef unsigned char FEM_Symmetries_t;
00062
00063
00065 class FEM_Sym_Desc : public PUP::able {
00066 public:
00067 virtual ~FEM_Sym_Desc();
00068
00070 virtual CkVector3d applyLoc(const CkVector3d &loc) const =0;
00071
00073 virtual CkVector3d applyVec(const CkVector3d &vec) const =0;
00074
00076 friend inline void operator|(PUP::er &p,FEM_Sym_Desc &a) {a.pup(p);}
00077 friend inline void operator|(PUP::er &p,FEM_Sym_Desc* &a) {
00078 PUP::able *pa=a; p(&pa); a=(FEM_Sym_Desc *)pa;
00079 }
00080 };
00081
00083 class FEM_Sym_Linear : public FEM_Sym_Desc {
00084 CkVector3d shift;
00085 public:
00086 FEM_Sym_Linear(const CkVector3d &shift_) :shift(shift_) {}
00087 FEM_Sym_Linear(CkMigrateMessage *m) {}
00088
00090 CkVector3d applyLoc(const CkVector3d &loc) const {return loc+shift;}
00091
00093 virtual CkVector3d applyVec(const CkVector3d &vec) const {return vec;}
00094
00095 virtual void pup(PUP::er &p);
00096 PUPable_decl(FEM_Sym_Linear);
00097 };
00098
00103 class FEM_Sym_List {
00104
00105 CkPupAblePtrVec<FEM_Sym_Desc> sym;
00106
00107 FEM_Sym_List(const FEM_Sym_List &src);
00108 public:
00109 FEM_Sym_List();
00110 void operator=(const FEM_Sym_List &src);
00111 ~FEM_Sym_List();
00112
00115 FEM_Symmetries_t add(FEM_Sym_Desc *desc);
00116
00118 void applyLoc(CkVector3d *loc,FEM_Symmetries_t sym) const;
00119
00121 void applyVec(CkVector3d *vec,FEM_Symmetries_t sym) const;
00122
00123 void pup(PUP::er &p);
00124 };
00125
00126
00130 template <class T>
00131 class BasicTable2d : public CkNoncopyable {
00132 protected:
00133 int rows;
00134 int cols;
00135 T *table;
00136 public:
00137 BasicTable2d(T *src,int cols_,int rows_)
00138 :rows(rows_), cols(cols_), table(src) {}
00139
00141 inline int size(void) const {return rows;}
00143 inline int width(void) const {return cols;}
00144
00145 T *getData(void) {return table;}
00146 const T *getData(void) const {return table;}
00147
00149 T operator() (int r,int c) const {return table[c+r*cols];}
00150 T &operator() (int r,int c) {return table[c+r*cols];}
00151
00153
00154 inline T *getRow(int r) {return &table[r*cols];}
00155 inline const T *getRow(int r) const {return &table[r*cols];}
00156 inline void getRow(int r,T *dest,T idxBase=0) const {
00157 const T *src=getRow(r);
00158 for (int c=0;c<cols;c++) dest[c]=src[c]+idxBase;
00159 }
00160 inline T *operator[](int r) {return getRow(r);}
00161 inline const T *operator[](int r) const {return getRow(r);}
00162 inline void setRow(int r,const T *src,T idxBase=0) {
00163 T *dest=getRow(r);
00164 for (int c=0;c<cols;c++) dest[c]=src[c]-idxBase;
00165 }
00166 inline void setRow(int r,T value) {
00167 T *dest=getRow(r);
00168 for (int c=0;c<cols;c++) dest[c]=value;
00169 }
00170
00172 void set(const T *src,T idxBase=0) {
00173 for (int r=0;r<rows;r++)
00174 for (int c=0;c<cols;c++)
00175 table[c+r*cols]=src[c+r*cols]-idxBase;
00176 }
00177 void setTranspose(const T *srcT,int idxBase=0) {
00178 for (int r=0;r<rows;r++)
00179 for (int c=0;c<cols;c++)
00180 table[c+r*cols]=srcT[r+c*rows]-idxBase;
00181 }
00182 void get(T *dest,T idxBase=0) const {
00183 for (int r=0;r<rows;r++)
00184 for (int c=0;c<cols;c++)
00185 dest[c+r*cols]=table[c+r*cols]+idxBase;
00186 }
00187 void getTranspose(T *destT,int idxBase=0) const {
00188 for (int r=0;r<rows;r++)
00189 for (int c=0;c<cols;c++)
00190 destT[r+c*rows]=table[c+r*cols]+idxBase;
00191 }
00192 void set(T value) {
00193 for (int r=0;r<rows;r++) setRow(r,value);
00194 }
00195 };
00196
00201 template <class T>
00202 class AllocTable2d : public BasicTable2d<T> {
00203 int max;
00204 T fill;
00205 T *allocTable;
00206 public:
00207 AllocTable2d(int cols_=0,int rows_=0,T fill_=0)
00208 :BasicTable2d<T>(NULL,cols_,rows_), max(0), fill(fill_),allocTable(NULL)
00209 {
00210 if (this->rows>0) allocate(this->rows);
00211 }
00212 ~AllocTable2d() {delete[] allocTable;}
00214 void allocate(int rows_) {
00215 allocate(this->width(),rows_);
00216 }
00218 void allocate(int cols_,int rows_,int max_=0) {
00219 if (cols_==this->cols && rows_<max) {
00220
00221 this->rows=rows_;
00222 return;
00223 }
00224 if (max_==0) {
00225 if (rows_==this->rows+1)
00226 max_=10+rows_+(rows_>>2);
00227 else
00228 max_=rows_;
00229 }
00230
00231 int oldRows=this->rows;
00232 this->cols=cols_;
00233 this->rows=rows_;
00234 this->max=max_;
00235 this->table=new T[max*this->cols];
00236
00237 int copyRows=0;
00238 if (allocTable!=NULL) {
00239 copyRows=oldRows;
00240 if (copyRows>max) copyRows=max;
00241 memcpy(this->table,allocTable,sizeof(T)*this->cols*copyRows);
00242 delete[] allocTable;
00243 }else{
00244 for (int r=copyRows;r<max;r++)
00245 this->setRow(r,fill);
00246 }
00247 allocTable = this->table;
00248 }
00249
00251 void pup(PUP::er &p) {
00252 p|this->rows; p|this->cols;
00253 if (this->table==NULL) allocate(this->rows);
00254 p(this->table,this->rows*this->cols);
00255 }
00256
00257 void pupSingle(PUP::er &p, int pupindx) {
00258 p|this->table[pupindx];
00259 }
00260
00261 friend void operator|(PUP::er &p,AllocTable2d<T> &t) {t.pup(p);}
00262
00264 T *push_back(void) {
00265 if (this->rows>=max)
00266 {
00267 int newMax=max+(max/4)+16;
00268 allocate(this->cols,this->rows,newMax);
00269 }
00270 this->rows++;
00271 return getRow(this->rows-1);
00272 }
00273
00278 void register_data(T *user,int len,int max_){
00279 if(allocTable != NULL){
00280 delete [] allocTable;
00281 allocTable = NULL;
00282 }
00283 this->table = user;
00284 this->rows = len;
00285 max = max_;
00286 }
00287 };
00288
00289
00290 class FEM_Entity;
00291 class FEM_Mesh;
00292
00293
00297 CLINKAGE const char *FEM_Get_entity_name(int entity,char *storage);
00298
00302 CLINKAGE const char *FEM_Get_attr_name(int attr,char *storage);
00303
00304
00305
00311 class FEM_Attribute {
00312 FEM_Entity *e;
00313 FEM_Attribute *ghost;
00314 int attr;
00315
00316 int width;
00317 int datatype;
00318 bool allocated;
00319
00320
00321
00322 void bad(const char *field,bool forRead,int cur,int next,const char *caller) const;
00323
00324 protected:
00330 virtual void allocate(int length,int width,int datatype) =0;
00331 public:
00332 FEM_Attribute(FEM_Entity *owner_,int myAttr_);
00333 virtual void pup(PUP::er &p);
00334 virtual void pupSingle(PUP::er &p, int pupindx);
00335 virtual ~FEM_Attribute();
00336
00338 inline void setGhost(FEM_Attribute *ghost_) { ghost=ghost_;}
00339
00341 inline bool isGhost(void) const { return ghost!=NULL; }
00342
00344 inline int getAttr(void) const {return attr;}
00345
00346 inline FEM_Entity *getEntity(void) {return e;}
00347
00350 int getLength(void) const;
00351 int getRealLength(void) const;
00352
00353 int getMax();
00354
00356 inline int getWidth(void) const { return width<0?0:width; }
00357 inline int getRealWidth(void) const { return width; }
00358
00360 inline int getDatatype(void) const { return datatype; }
00361
00367 void setLength(int l,const char *caller="");
00368
00373 void setWidth(int w,const char *caller="");
00374
00379 void setDatatype(int dt,const char *caller="");
00380
00386 virtual void copyShape(const FEM_Attribute &src);
00387
00390 void tryAllocate(void);
00391
00393 inline void reallocate(void) { allocated=false; tryAllocate(); }
00394
00396 inline bool isAllocated(void) const {return allocated;}
00397
00406 virtual void set(const void *src, int firstItem,int length,
00407 const IDXL_Layout &layout, const char *caller);
00408
00418 virtual void get(void *dest, int firstItem,int length,
00419 const IDXL_Layout &layout, const char *caller) const;
00420
00422 virtual void copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity) =0;
00423
00428 virtual void register_data(void *dest, int length,int max,
00429 const IDXL_Layout &layout, const char *caller);
00430
00431 };
00432 PUPmarshall(FEM_Attribute)
00433
00434
00435
00439 class FEM_DataAttribute : public FEM_Attribute {
00440 typedef FEM_Attribute super;
00441 AllocTable2d<unsigned char> *char_data;
00442 AllocTable2d<int> *int_data;
00443 AllocTable2d<float> *float_data;
00444 AllocTable2d<double> *double_data;
00445 protected:
00446 virtual void allocate(int length,int width,int datatype);
00447 public:
00448 FEM_DataAttribute(FEM_Entity *owner,int myAttr);
00449 virtual void pup(PUP::er &p);
00450 virtual void pupSingle(PUP::er &p, int pupindx);
00451 ~FEM_DataAttribute();
00452
00453 AllocTable2d<unsigned char> &getChar(void) {return *char_data;}
00454 const AllocTable2d<unsigned char> &getChar(void) const {return *char_data;}
00455
00456 AllocTable2d<int> &getInt(void) {return *int_data;}
00457 const AllocTable2d<int> &getInt(void) const {return *int_data;}
00458
00459 AllocTable2d<double> &getDouble(void) {return *double_data;}
00460
00461
00462 virtual void set(const void *src, int firstItem,int length,
00463 const IDXL_Layout &layout, const char *caller);
00464
00465 virtual void get(void *dest, int firstItem,int length,
00466 const IDXL_Layout &layout, const char *caller) const;
00467
00468 virtual void register_data(void *dest, int length,int max,
00469 const IDXL_Layout &layout, const char *caller);
00470
00471
00473 virtual void copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity);
00474
00475
00476 void interpolate(int A,int B,int D,double frac);
00477 void interpolate(int *iNodes,int rNode,int k);
00478 };
00479 PUPmarshall(FEM_DataAttribute)
00480
00481
00485 class FEM_IndexAttribute : public FEM_Attribute {
00486 public:
00488 class Checker {
00489 public:
00490 virtual ~Checker();
00491
00496 virtual void check(int row,const BasicTable2d<int> &table,
00497 const char *caller) const =0;
00498 };
00499 private:
00500 typedef FEM_Attribute super;
00501 AllocTable2d<int> idx;
00502 Checker *checker;
00503 protected:
00504 virtual void allocate(int length,int width,int datatype);
00505 public:
00506 FEM_IndexAttribute(FEM_Entity *owner,int myAttr, Checker *checker_=NULL);
00507 virtual void pup(PUP::er &p);
00508 virtual void pupSingle(PUP::er &p, int pupindx);
00509 ~FEM_IndexAttribute();
00510
00511 AllocTable2d<int> &get(void) {return idx;}
00512 const AllocTable2d<int> &get(void) const {return idx;}
00513
00514 virtual void set(const void *src, int firstItem,int length,
00515 const IDXL_Layout &layout, const char *caller);
00516
00517 virtual void get(void *dest, int firstItem,int length,
00518 const IDXL_Layout &layout, const char *caller) const;
00519
00520 virtual void register_data(void *dest, int length, int max,
00521 const IDXL_Layout &layout, const char *caller);
00522
00524 virtual void copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity);
00525 };
00526 PUPmarshall(FEM_IndexAttribute)
00527
00528
00529
00530
00531
00532
00533
00534 class FEM_VarIndexAttribute : public FEM_Attribute{
00535 public:
00536 class ID{
00537
00538
00539 public:
00540 int type;
00541 int id;
00542 ID(){
00543 type=-1;
00544 id = -1;
00545 };
00546 ID(int _type,int _id){
00547 if(_id < 0) {
00548 type = -(_type+1);
00549 id = FEM_To_ghost_index(_id);
00550 }
00551 else {
00552 type = _type;
00553 id = _id;
00554 }
00555 };
00556 bool operator ==(const ID &rhs)const {
00557 return (type == rhs.type) && (id == rhs.id);
00558 }
00559 virtual void pup(PUP::er &p){
00560 p | type;
00561 p | id;
00562 };
00563
00564 static ID createNodeID(int type,int node){
00565 ID temp(type, node);
00566 return temp;
00567 }
00568 int getSignedId() {
00569 if(type<0){
00570 return FEM_From_ghost_index(id);
00571 }
00572 else return id;
00573 }
00574 };
00575 private:
00576 typedef FEM_Attribute super;
00577 CkVec<CkVec<ID> > idx;
00578 int oldlength;
00579 protected:
00580 virtual void allocate(int _length,int _width,int _datatype){
00581 if(_length > oldlength){
00582 setWidth(1,"allocate");
00583 oldlength = _length*2;
00584 idx.reserve(oldlength);
00585 for(int i=idx.size();i<oldlength;i++){
00586 CkVec<ID> tempVec;
00587 idx.insert(i,tempVec);
00588 }
00589 }
00590 };
00591 public:
00592 FEM_VarIndexAttribute(FEM_Entity *owner,int myAttr);
00593 ~FEM_VarIndexAttribute(){};
00594 virtual void pup(PUP::er &p);
00595 virtual void pupSingle(PUP::er &p, int pupindx);
00596 CkVec<CkVec<ID> > &get(){return idx;};
00597 const CkVec<CkVec<ID> > &get() const {return idx;};
00598
00599 virtual void set(const void *src,int firstItem,int length,
00600 const IDXL_Layout &layout,const char *caller);
00601
00602 virtual void get(void *dest, int firstItem,int length,
00603 const IDXL_Layout &layout, const char *caller) const;
00604
00605 virtual void copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity);
00606
00607 int findInRow(int row,const ID &data);
00608
00609 void print();
00610 };
00611
00612
00613 class l2g_t;
00619 class FEM_Entity {
00620 typedef CkVec<FEM_Symmetries_t> sym_t;
00621 int length;
00622 int max;
00623 FEM_Mesh_alloc_fn resize;
00624 void *args;
00625
00636 CkVec<FEM_Attribute *> attributes;
00637
00643 FEM_DataAttribute *coord;
00644 void allocateCoord(void);
00645
00652 FEM_DataAttribute *sym;
00653 void allocateSym(void);
00654
00659 FEM_IndexAttribute *globalno;
00660 void allocateGlobalno(void);
00661
00662
00663
00664
00665
00666 void allocateBoundary();
00667
00669
00671 FEM_DataAttribute *meshSizing;
00672 void allocateMeshSizing(void);
00673
00674
00675
00676
00677
00678
00679
00680 FEM_DataAttribute *valid;
00681 unsigned int first_invalid, last_invalid;
00682
00683 protected:
00697 virtual void create(int attr,const char *caller);
00698
00703 void add(FEM_Attribute *attribute);
00704 public:
00705
00706 FEM_Entity *ghost;
00707
00708 FEM_Comm ghostSend;
00709 FEM_Comm ghostRecv;
00710
00711 FEM_Entity(FEM_Entity *ghost_);
00712 void pup(PUP::er &p);
00713 virtual ~FEM_Entity();
00714
00716 bool isGhost(void) const {return ghost==NULL;}
00717
00719 FEM_Entity *getGhost(void) {return ghost;}
00720 const FEM_Entity *getGhost(void) const {return ghost;}
00721
00723 inline int size(void) const {return length==-1?0:length;}
00724 inline int realsize(void) const {return length;}
00725
00726
00727 inline int getMax() { if(max > 0) return max; else return length;}
00728
00730 virtual const char *getName(void) const =0;
00731
00733 void copyShape(const FEM_Entity &src);
00734
00739 void setLength(int newlen);
00740
00746 void setMaxLength(int newLen,int newMaxLen,void *args,FEM_Mesh_alloc_fn fn);
00747
00750 void copyEntity(int dstEntity,const FEM_Entity &src,int srcEntity);
00751
00754 int push_back(const FEM_Entity &src,int srcEntity);
00755
00761 FEM_Attribute *lookup(int attr,const char *caller);
00762
00763
00767 int getAttrs(int *attrs) const {
00768 int len=attributes.size();
00769 for (int i=0;i<len;i++)
00770 attrs[i]=attributes[i]->getAttr();
00771 return len;
00772 }
00773
00777 void allocateValid();
00778 void set_valid(unsigned int idx, bool isNode);
00779 void set_invalid(unsigned int idx, bool isNode);
00780 int is_valid(unsigned int idx);
00781 unsigned int count_valid();
00782 unsigned int get_next_invalid(FEM_Mesh *m, bool isNode, bool isGhost);
00783 virtual bool hasConn(unsigned int idx)=0;
00787 void set_coord(int idx, double x, double y);
00788 void set_coord(int idx, double x, double y, double z);
00789
00793 CkVec<FEM_Attribute *>* getAttrVec(){
00794 return &attributes;
00795 }
00796
00797
00798 inline FEM_DataAttribute *getCoord(void) {return coord;}
00799 inline const FEM_DataAttribute *getCoord(void) const {return coord;}
00800
00801
00802 const FEM_Symmetries_t *getSymmetries(void) const {
00803 if (sym==NULL) return NULL;
00804 else return (const FEM_Symmetries_t *)sym->getChar()[0];
00805 }
00806 FEM_Symmetries_t getSymmetries(int r) const {
00807 if (sym==NULL) return FEM_Symmetries_t(0);
00808 else return sym->getChar()(r,0);
00809 }
00810 void setSymmetries(int r,FEM_Symmetries_t s);
00811
00812
00813 bool hasGlobalno(void) const {return globalno!=0;}
00814 int getGlobalno(int r) const {
00815 if (globalno==0) return -1;
00816 return globalno->get()(r,0);
00817 }
00818 void setGlobalno(int r,int g);
00819 void setAscendingGlobalno(void);
00820 void setAscendingGlobalno(int base);
00821 void copyOldGlobalno(const FEM_Entity &e);
00822
00823
00824 bool hasMeshSizing(void) const {return meshSizing!=0;}
00825 double getMeshSizing(int r);
00826 void setMeshSizing(int r,double s);
00827 void setMeshSizing(double *sf);
00828
00829
00830 FEM_Comm &setGhostSend(void) { return ghostSend; }
00831 const FEM_Comm &getGhostSend(void) const { return ghostSend; }
00832 FEM_Comm &setGhostRecv(void) {
00833 if (ghost==NULL) return ghostRecv;
00834 else return ghost->ghostRecv;
00835 }
00836 const FEM_Comm &getGhostRecv(void) const { return ghost->ghostRecv; }
00837 FEM_Comm_Holder ghostIDXL;
00838
00839 void addVarIndexAttribute(int code){
00840 FEM_VarIndexAttribute *varAttribute = new FEM_VarIndexAttribute(this,code);
00841 add(varAttribute);
00842 }
00843
00844 void print(const char *type,const IDXL_Print_Map &map);
00845 };
00846 PUPmarshall(FEM_Entity)
00847
00848
00849 inline int FEM_Attribute::getLength(void) const { return e->size(); }
00850 inline int FEM_Attribute::getRealLength(void) const { return e->realsize(); }
00851 inline int FEM_Attribute::getMax(){ return e->getMax();}
00852
00859 class FEM_Elem;
00860 class FEM_Node : public FEM_Entity {
00861 typedef FEM_Entity super;
00862
00868 FEM_DataAttribute *primary;
00869 void allocatePrimary(void);
00870
00871 void allocateElemAdjacency();
00872 void allocateNodeAdjacency();
00873
00874 FEM_VarIndexAttribute *elemAdjacency;
00875 FEM_VarIndexAttribute *nodeAdjacency;
00876 typedef FEM_VarIndexAttribute::ID var_id;
00877 protected:
00878 virtual void create(int attr,const char *caller);
00879 public:
00880 FEM_Comm shared;
00881 FEM_Comm_Holder sharedIDXL;
00882
00883 FEM_Node(FEM_Node *ghost_);
00884 void pup(PUP::er &p);
00885 ~FEM_Node();
00886
00887 virtual const char *getName(void) const;
00888
00889 inline bool getPrimary(int nodeNo) const {
00890 if (primary==NULL) return true;
00891 else return primary->getChar()(nodeNo,0);
00892 }
00893 inline void setPrimary(int nodeNo,bool isPrimary) {
00894 if (primary==NULL) allocatePrimary();
00895 primary->getChar()(nodeNo,0)=isPrimary;
00896 }
00897 void fillElemAdjacencyTable(int type,const FEM_Elem &elem);
00898 void setElemAdjacency(int type,const FEM_Elem &elem);
00899 void fillNodeAdjacency(const FEM_Elem &elem);
00900 void setNodeAdjacency(const FEM_Elem &elem);
00901 void fillNodeAdjacencyForElement(int node,int nodesPerElem,const int *conn,FEM_VarIndexAttribute *adjacencyAttr);
00902 bool hasConn(unsigned int idx);
00903 void print(const char *type,const IDXL_Print_Map &map);
00904 };
00905 PUPmarshall(FEM_Node)
00906
00907
00912 class FEM_Elem:public FEM_Entity {
00913 typedef FEM_Entity super;
00914 protected:
00915 typedef AllocTable2d<int> conn_t;
00916
00917 int tuplesPerElem;
00918
00919
00920 FEM_IndexAttribute *conn;
00921 FEM_IndexAttribute *elemAdjacency;
00922 FEM_IndexAttribute *elemAdjacencyTypes;
00923
00924 public:
00925
00926 FEM_Elem(const FEM_Mesh &mesh_, FEM_Elem *ghost_);
00927 void pup(PUP::er &p);
00928 ~FEM_Elem();
00929
00930 virtual const char *getName(void) const;
00931
00933 inline conn_t &setConn(void) {return conn->get();}
00934 inline const conn_t &getConn(void) const {return conn->get();}
00935
00936 void print(const char *type,const IDXL_Print_Map &map);
00937
00938 void create(int attr,const char *caller);
00939
00940 void allocateElemAdjacency();
00941
00942 FEM_IndexAttribute *getElemAdjacency(){return elemAdjacency;}
00943
00944
00945 int getConn(int elem,int nodeNo) const {return conn->get()(elem,nodeNo);}
00946 int getNodesPer(void) const {return conn->get().width();}
00947 int *connFor(int i) {return conn->get().getRow(i);}
00948 const int *connFor(int i) const {return conn->get().getRow(i);}
00949 void connIs(int i,const int *src) {conn->get().setRow(i,src);}
00950 bool hasConn(unsigned int idx);
00951 };
00952 PUPmarshall(FEM_Elem)
00953
00954
00955
00956
00963 class FEM_Sparse : public FEM_Elem {
00964 typedef FEM_Elem super;
00965 typedef AllocTable2d<int> elem_t;
00966
00975 FEM_IndexAttribute *elem;
00976 void allocateElem(void);
00977 const FEM_Mesh &mesh;
00978 protected:
00979 virtual void create(int attr,const char *caller);
00980 public:
00981 FEM_Sparse(const FEM_Mesh &mesh_, FEM_Sparse *ghost_);
00982 void pup(PUP::er &p);
00983 virtual ~FEM_Sparse();
00984
00985 virtual const char *getName(void) const;
00986
00988 bool hasElements(void) const {return elem!=NULL;}
00989
00991 inline elem_t &setElem(void) {return elem->get();}
00992 inline const elem_t &getElem(void) const {return elem->get();}
00993 };
00994 PUPmarshall(FEM_Sparse)
00995
00996
00998 class FEM_Userdata_pupfn {
00999 FEM_Userdata_fn fn;
01000 void *data;
01001 public:
01002 FEM_Userdata_pupfn(FEM_Userdata_fn fn_,void *data_)
01003 :fn(fn_), data(data_) {}
01005 void pup(PUP::er &p) {
01006 (fn)((pup_er)&p,data);
01007 }
01008 };
01009
01012 class FEM_Userdata_item {
01013 CkVec<char> data;
01014 public:
01015 int tag;
01016 FEM_Userdata_item(int tag_=-1) {tag=tag_;}
01017
01019 bool hasStored(void) const {return data.size()!=0;}
01020
01022 void store(FEM_Userdata_pupfn &f) {
01023 data.resize(PUP::size(f));
01024 PUP::toMemBuf(f,&data[0],data.size());
01025 }
01027 void restore(FEM_Userdata_pupfn &f) {
01028 PUP::fromMemBuf(f,&data[0],data.size());
01029 }
01030
01032 void pup(PUP::er &p) {
01033 p|tag;
01034 p|data;
01035 }
01036 };
01037
01040 class FEM_Userdata_list {
01041 CkVec<FEM_Userdata_item> list;
01042 public:
01043 FEM_Userdata_item &find(int tag) {
01044 for (int i=0;i<list.size();i++)
01045 if (list[i].tag==tag)
01046 return list[i];
01047
01048 list.push_back(FEM_Userdata_item(tag));
01049 return list[list.size()-1];
01050 }
01051 int size(){
01052 return list.size();
01053 }
01054 void pup(PUP::er &p) {p|list;}
01055 };
01056
01057
01058 void FEM_Index_Check(const char *caller,const char *entityType,int type,int maxType);
01059 void FEM_Is_NULL(const char *caller,const char *entityType,int type);
01060
01073 template <class T>
01074 class FEM_Entity_Types {
01075 CkVec<T *> types;
01076 const FEM_Mesh &mesh;
01077 const char *name;
01078
01079 public:
01080 FEM_Entity_Types(const FEM_Mesh &mesh_,const char *name_)
01081 :mesh(mesh_), name(name_) {}
01082 void pup(PUP::er &p) {
01083
01084 int n=types.size();
01085 p|n;
01086 for (int i=0;i<n;i++) {
01087 int isNULL=0;
01088 if (!p.isUnpacking()) isNULL=(types[i]==NULL);
01089 p|isNULL;
01090 if (!isNULL) set(i,"pup").pup(p);
01091 }
01092 }
01093 ~FEM_Entity_Types() {
01094 for (int i=0;i<types.size();i++)
01095 if (types[i]) delete types[i];
01096 }
01097
01099 inline int size(void) const {return types.size();}
01100
01102 const T &get(int type,const char *caller="") const {
01103 FEM_Index_Check(caller,name,type,types.size());
01104 const T *ret=types[type];
01105 if (ret==NULL) FEM_Is_NULL(caller,name,type);
01106 return *ret;
01107 }
01108
01110 bool has(int type) const {
01111 if (type>=types.size()) return false;
01112 return types[type]!=NULL;
01113 }
01114
01116 T &set(int type,const char *caller="") {
01117 if (type<0) FEM_Index_Check(caller,name,type,types.size());
01118 while (types.size()<=type) types.push_back(NULL);
01119 if (types[type]==NULL) {
01120 T *ghost=new T(mesh,NULL);
01121 types[type]=new T(mesh,ghost);
01122 }
01123 return *types[type];
01124 }
01125
01127 inline T &operator[] (int type) { return set(type); }
01128 inline const T &operator[] (int type) const { return get(type); }
01129
01130 };
01131
01132
01133 inline int zeroToMinusOne(int i) {
01134 if (i==0) return -1;
01135 return i;
01136 }
01137
01138
01139
01140
01145 class FEM_ElemAdj_Layer;
01146 class femMeshModify;
01147 class FEM_Mesh : public CkNoncopyable {
01149 FEM_Sym_List symList;
01150 bool m_isSetting;
01151 femMeshModify *fmMM;
01152
01153 void checkElemType(int elType,const char *caller) const;
01154 void checkSparseType(int uniqueID,const char *caller) const;
01155
01156 FEM_ElemAdj_Layer* lastElemAdjLayer;
01157
01158 public:
01159 void setFemMeshModify(femMeshModify *m);
01160
01161 FEM_Mesh();
01162 void pup(PUP::er &p);
01163 ~FEM_Mesh();
01164
01166 FEM_Node node;
01167
01169 FEM_Entity_Types<FEM_Elem> elem;
01170
01172 FEM_Entity_Types<FEM_Sparse> sparse;
01173
01175 FEM_Userdata_list udata;
01176
01178 void setSymList(const FEM_Sym_List &src) {symList=src;}
01179 const FEM_Sym_List &getSymList(void) const {return symList;}
01180
01183 void copyShape(const FEM_Mesh &src);
01184
01185
01186 femMeshModify *getfmMM();
01187
01188
01189 FEM_Entity &setCount(int elTypeOrMinusOne) {
01190 if (elTypeOrMinusOne==-1) return node;
01191 else return elem[chkET(elTypeOrMinusOne)];
01192 }
01193 const FEM_Entity &getCount(int elTypeOrMinusOne) const {
01194 if (elTypeOrMinusOne==-1) return node;
01195 else return elem[chkET(elTypeOrMinusOne)];
01196 }
01197 FEM_Elem &setElem(int elType) {return elem[chkET(elType)];}
01198 const FEM_Elem &getElem(int elType) const {return elem[chkET(elType)];}
01199 int chkET(int elType) const;
01200
01202 FEM_Entity *lookup(int entity,const char *caller);
01203 const FEM_Entity *lookup(int entity,const char *caller) const;
01204
01206 inline bool isSetting(void) const {return m_isSetting;}
01207 void becomeSetting(void) {m_isSetting=true;}
01208 void becomeGetting(void) {m_isSetting=false;}
01209
01210 int nElems() const
01211 {return nElems(elem.size());}
01213 int nElems(int t) const;
01215 int getGlobalElem(int elType,int elNo) const;
01217 void setAscendingGlobalno(void);
01219 void setAbsoluteGlobalno();
01220
01221 void copyOldGlobalno(const FEM_Mesh &m);
01222 void print(int idxBase);
01224 int getEntities(int *entites);
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 void createNodeElemAdj();
01235 void createNodeNodeAdj();
01236 void createElemElemAdj();
01237
01238 FEM_ElemAdj_Layer *getElemAdjLayer(void);
01239
01240
01241
01242
01245 void e2e_getAll(int e, int *neighborss, int etype=0);
01247 int e2e_getNbr(int e, short idx, int etype=0);
01250 int e2e_getIndex(int e, int nbr, int etype=0);
01253 void e2e_setAll(int e, int *neighbors, int etype=0);
01255 void e2e_setIndex(int e, short idx, int newElem, int etype=0);
01257 void e2e_replace(int e, int oldNbr, int newNbr, int etype=0);
01259 void e2e_removeAll(int e, int etype=0);
01260
01261
01262
01265 void e2n_getAll(int e, int *adjnodes, int etype=0);
01267 int e2n_getNode(int e, short idx, int etype=0);
01270 short e2n_getIndex(int e, int n, int etype=0);
01273 void e2n_setAll(int e, int *adjnodes, int etype=0);
01275 void e2n_setIndex(int e, short idx, int newNode, int etype=0);
01277 void e2n_replace(int e, int oldNode, int newNode, int etype=0);
01279 void e2n_removeAll(int e, int etype=0);
01280
01281
01282
01285 void n2n_getAll(int n, int **adjnodes, int *sz);
01287 void n2n_add(int n, int newNode);
01289 void n2n_remove(int n, int oldNode);
01291 void n2n_replace(int n, int oldNode, int newNode);
01293 void n2n_removeAll(int n);
01295 int n2n_exists(int n, int queryNode);
01296
01297
01301 void n2e_getAll(int n, int **adjelements, int *sz);
01303 void n2e_add(int n, int newElem);
01305 void n2e_remove(int n, int oldElem);
01307 void n2e_replace(int n, int oldElem, int newElem);
01309 void n2e_removeAll(int n);
01310
01314 int getElementOnEdge(int n1, int n2);
01315
01317 void get2ElementsOnEdge(int n1, int n2, int *result_e1, int *result_e2) ;
01318
01319
01320
01321
01322
01323 };
01324 PUPmarshall(FEM_Mesh)
01325 FEM_Mesh *FEM_Mesh_lookup(int fem_mesh,const char *caller);
01326 FEM_Entity *FEM_Entity_lookup(int fem_mesh,int entity,const char *caller);
01327 FEM_Attribute *FEM_Attribute_lookup(int fem_mesh,int entity,int attr,const char *caller);
01328
01329 void FEM_Mesh_data_layout(int fem_mesh,int entity,int attr,
01330 void *data, int firstItem,int length, const IDXL_Layout &layout);
01331
01332
01333 void FEM_Register_array_layout(int fem_mesh,int entity,int attr,void *data,int firstItem,const IDXL_Layout &layout);
01334 void FEM_Register_entity_impl(int fem_mesh,int entity,void *args,int len,int max,FEM_Mesh_alloc_fn fn);
01336 FEM_Mesh *FEM_Mesh_assemble(int nchunks,FEM_Mesh **chunks);
01337
01338 FILE *FEM_openMeshFile(const char *prefix,int chunkNo,int nchunks,bool forRead);
01339 FEM_Mesh *FEM_readMesh(const char *prefix,int chunkNo,int nChunks);
01340 void FEM_writeMesh(FEM_Mesh *m,const char *prefix,int chunkNo,int nChunks);
01341
01342
01343
01344
01345 #endif