00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <assert.h>
00010 #include "fem.h"
00011 #include "fem_impl.h"
00012 #include "charm-api.h"
00013 #include "fem_mesh_modify.h"
00014
00015 extern int femVersion;
00016
00017
00018 FEM_Comm_Holder::FEM_Comm_Holder(FEM_Comm *sendComm, FEM_Comm *recvComm)
00019 :comm(sendComm,recvComm)
00020 {
00021 registered=false;
00022 idx=-1;
00023 }
00024 void FEM_Comm_Holder::registerIdx(IDXL_Chunk *c) {
00025 assert(!registered);
00026 IDXL_Chunk *owner=c;
00027 if (idx!=-1)
00028 idx=owner->addStatic(&comm,idx);
00029 else
00030 idx=owner->addStatic(&comm);
00031 }
00032 void FEM_Comm_Holder::pup(PUP::er &p) {
00033 p|idx;
00034 if (p.isUnpacking() && idx!=-1)
00035 {
00036 registerIdx(IDXL_Chunk::get("FEM_Comm_Holder::pup"));
00037 }
00038 }
00039
00040 FEM_Comm_Holder::~FEM_Comm_Holder(void)
00041 {
00042 if (registered)
00043 {
00044 const char *caller="FEM_Comm_Holder::~FEM_Comm_Holder";
00045 IDXL_Chunk *owner=IDXL_Chunk::getNULL();
00046 if (owner) owner->destroy(idx,caller);
00047 }
00048 }
00049
00050
00051
00052 static void checkIsSet(int fem_mesh,bool wantSet,const char *caller) {
00053 if (FEM_Mesh_is_set(fem_mesh)!=wantSet) {
00054 const char *msg=wantSet?"This mesh (%d) is not a setting mesh":
00055 "This mesh (%d) is not a getting mesh";
00056 FEM_Abort(caller,msg,fem_mesh);
00057 }
00058 }
00059
00060
00061 CLINKAGE void
00062 FEM_Mesh_conn(int fem_mesh,int entity,
00063 int *conn, int firstItem, int length, int width)
00064 {
00065 FEM_Mesh_data(fem_mesh,entity,FEM_CONN, conn, firstItem,length, FEM_INDEX_0, width);
00066 }
00067 FLINKAGE void
00068 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(int *fem_mesh,int *entity,
00069 int *conn, int *firstItem,int *length, int *width)
00070 {
00071
00072 FEM_Mesh_data(*fem_mesh,*entity,FEM_CONN, conn, *firstItem-1,*length, FEM_INDEX_1, *width);
00073 }
00074
00075 CLINKAGE void
00076 FEM_Mesh_set_conn(int fem_mesh,int entity,
00077 const int *conn, int firstItem,int length, int width)
00078 {
00079 checkIsSet(fem_mesh,true,"FEM_Mesh_set_conn");
00080 FEM_Mesh_conn(fem_mesh,entity,(int *)conn,firstItem,length,width);
00081 }
00082 FLINKAGE void
00083 FTN_NAME(FEM_MESH_SET_CONN,fem_mesh_set_conn)(int *fem_mesh,int *entity,
00084 const int *conn, int *firstItem,int *length, int *width)
00085 {
00086 checkIsSet(*fem_mesh,true,"fem_mesh_set_conn");
00087 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(fem_mesh,entity,(int *)conn,firstItem,length,width);
00088 }
00089
00090 CLINKAGE void
00091 FEM_Mesh_get_conn(int fem_mesh,int entity,
00092 int *conn, int firstItem,int length, int width)
00093 {
00094 checkIsSet(fem_mesh,false,"FEM_Mesh_get_conn");
00095 FEM_Mesh_conn(fem_mesh,entity,conn,firstItem,length,width);
00096 }
00097 FLINKAGE void
00098 FTN_NAME(FEM_MESH_GET_CONN,fem_mesh_get_conn)(int *fem_mesh,int *entity,
00099 int *conn, int *firstItem,int *length, int *width)
00100 {
00101 checkIsSet(*fem_mesh,false,"fem_mesh_get_conn");
00102 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(fem_mesh,entity,conn,firstItem,length,width);
00103 }
00104
00105
00106
00107 CLINKAGE void
00108 FEM_Mesh_data(int fem_mesh,int entity,int attr,
00109 void *data, int firstItem,int length, int datatype,int width)
00110 {
00111 IDXL_Layout lo(datatype,width);
00112 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,lo);
00113 }
00114
00115 FORTRAN_AS_C(FEM_MESH_DATA,FEM_Mesh_data,fem_mesh_data,
00116 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00117 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00118 )
00119
00120
00121 CLINKAGE void
00122 FEM_Mesh_set_data(int fem_mesh,int entity,int attr,
00123 const void *data, int firstItem,int length, int datatype,int width)
00124 {
00125 checkIsSet(fem_mesh,true,"FEM_Mesh_set_data");
00126 FEM_Mesh_data(fem_mesh,entity,attr,(void *)data,firstItem,length,datatype,width);
00127 }
00128 FORTRAN_AS_C(FEM_MESH_SET_DATA,FEM_Mesh_set_data,fem_mesh_set_data,
00129 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00130 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00131 )
00132
00133 CLINKAGE void
00134 FEM_Mesh_get_data(int fem_mesh,int entity,int attr,
00135 void *data, int firstItem,int length, int datatype,int width)
00136 {
00137 checkIsSet(fem_mesh,false,"FEM_Mesh_get_data");
00138 FEM_Mesh_data(fem_mesh,entity,attr,data,firstItem,length,datatype,width);
00139 }
00140 FORTRAN_AS_C(FEM_MESH_GET_DATA,FEM_Mesh_get_data,fem_mesh_get_data,
00141 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00142 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00143 )
00144
00145 CLINKAGE void
00146 FEM_Mesh_data_layout(int fem_mesh,int entity,int attr,
00147 void *data, int firstItem,int length, IDXL_Layout_t layout)
00148 {
00149 const char *caller="FEM_Mesh_data_layout";
00150 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,
00151 IDXL_Layout_List::get().get(layout,caller));
00152 }
00153
00154 FORTRAN_AS_C(FEM_MESH_DATA_LAYOUT,FEM_Mesh_data_layout,fem_mesh_data_layout,
00155 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *layout),
00156 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*layout)
00157 )
00158
00159 CLINKAGE void
00160 FEM_Mesh_data_offset(int fem_mesh,int entity,int attr,
00161 void *data, int firstItem,int length,
00162 int type,int width, int offsetBytes,int distanceBytes,int skewBytes)
00163 {
00164 const char *caller="FEM_Mesh_data_offset";
00165 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,
00166 IDXL_Layout(type,width,offsetBytes,distanceBytes,skewBytes));
00167 }
00168 FORTRAN_AS_C(FEM_MESH_DATA_OFFSET,FEM_Mesh_data_offset,fem_mesh_data_offset,
00169 (int *fem_mesh,int *entity,int *attr,
00170 void *data,int *firstItem,int *length,
00171 int *type,int *width,int *offset,int *distance,int *skew),
00172 (*fem_mesh,*entity,*attr,
00173 data,*firstItem-1,*length,
00174 *type,*width,*offset,*distance,*skew)
00175 )
00176
00177
00178 void FEM_Register_array(int fem_mesh,int entity,int attr,
00179 void *data, int datatype,int width,int firstItem){
00180 IDXL_Layout lo(datatype,width);
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 FEM_Register_array_layout(fem_mesh,entity,attr,data,firstItem,lo);
00191 }
00192
00193 void FEM_Register_array_layout(int fem_mesh,int entity,int attr,
00194 void *data, IDXL_Layout_t layout,int firstItem){
00195 const char *caller="FEM_Register_array_layout";
00196 FEM_Register_array_layout(fem_mesh,entity,attr,data,firstItem,
00197 IDXL_Layout_List::get().get(layout,caller));
00198
00199 }
00200
00201
00202 CLINKAGE void
00203 FEM_Register_array(int fem_mesh,int entity,int attr,
00204 void *data, int datatype,int width)
00205 {
00206 FEM_Register_array(fem_mesh,entity,attr,data,datatype,width,0);
00207 }
00208
00209 CLINKAGE void
00210 FEM_Register_array_layout(int fem_mesh,int entity,int attr,
00211 void *data, IDXL_Layout_t layout){
00212 FEM_Register_array_layout(fem_mesh,entity,attr,data,layout,0);
00213 }
00214
00215
00216 CLINKAGE void
00217 FEM_Register_entity(int fem_mesh,int entity,void *data,
00218 int len,int max,FEM_Mesh_alloc_fn fn) {
00219 FEM_Register_entity_impl(fem_mesh,entity,data,len,max,fn);
00220 }
00221
00224 FORTRAN_AS_C(FEM_REGISTER_ARRAY,FEM_Register_array,fem_register_array,
00225 (int *fem_mesh,int *entity,int *attr,void *data,int *datatype,int *width),(*fem_mesh,*entity,*attr,data,*datatype,*width,0))
00226
00227
00228 FORTRAN_AS_C(FEM_REGISTER_ARRAY_LAYOUT,FEM_Register_array_layout,fem_register_array_layout,
00229 (int *fem_mesh,int *entity,int *attr,void *data,int *layout),(*fem_mesh,*entity,*attr,data,*layout,0))
00230
00231 FORTRAN_AS_C(FEM_REGISTER_ENTITY,FEM_Register_entity,fem_register_entity,
00232 (int *fem_mesh,int *entity,void *data,int *len,int *max,FEM_Mesh_alloc_fn fn),(*fem_mesh,*entity,data,*len,*max,fn))
00233
00234
00235
00236 CLINKAGE void
00237 FEM_Mesh_pup(int fem_mesh,int dataTag,FEM_Userdata_fn fn,void *data) {
00238 const char *caller="FEM_Mesh_pup"; FEMAPI(caller);
00239 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00240 FEM_Userdata_item &i=m->udata.find(dataTag);
00241 FEM_Userdata_pupfn f(fn,data);
00242 if (m->isSetting()) i.store(f);
00243 else {
00244 if (!i.hasStored())
00245 FEM_Abort(caller,"Never stored any user data at tag %d",dataTag);
00246 i.restore(f);
00247 }
00248 }
00249 FORTRAN_AS_C(FEM_MESH_PUP,FEM_Mesh_pup,fem_mesh_pup,
00250 (int *m,int *t,FEM_Userdata_fn fn,void *data), (*m,*t,fn,data))
00251
00252
00253 CLINKAGE void
00254 FEM_Mesh_set_length(int fem_mesh,int entity,int newLength) {
00255 const char *caller="FEM_Mesh_set_length"; FEMAPI(caller);
00256 checkIsSet(fem_mesh,true,caller);
00257 FEM_Entity_lookup(fem_mesh,entity,caller)->setLength(newLength);
00258 }
00259 FORTRAN_AS_C(FEM_MESH_SET_LENGTH,FEM_Mesh_set_length,fem_mesh_set_length,
00260 (int *fem_mesh,int *entity,int *newLength),
00261 (*fem_mesh,*entity,*newLength)
00262 )
00263
00264
00265 CLINKAGE int
00266 FEM_Mesh_get_length(int fem_mesh,int entity) {
00267 const char *caller="FEM_Mesh_get_length"; FEMAPI(caller);
00268 int len=FEM_Entity_lookup(fem_mesh,entity,caller)->size();
00269 return len;
00270 }
00271 FORTRAN_AS_C_RETURN(int,
00272 FEM_MESH_GET_LENGTH,FEM_Mesh_get_length,fem_mesh_get_length,
00273 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00274 )
00275
00276
00277 CLINKAGE void
00278 FEM_Mesh_set_width(int fem_mesh,int entity,int attr,int newWidth) {
00279 const char *caller="FEM_Mesh_set_width";
00280 FEMAPI(caller);
00281 checkIsSet(fem_mesh,true,caller);
00282 FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->setWidth(newWidth,caller);
00283 }
00284 FORTRAN_AS_C(FEM_MESH_SET_WIDTH,FEM_Mesh_set_width,fem_mesh_set_width,
00285 (int *fem_mesh,int *entity,int *attr,int *newWidth),
00286 (*fem_mesh,*entity,*attr,*newWidth)
00287 )
00288
00289 CLINKAGE int
00290 FEM_Mesh_get_width(int fem_mesh,int entity,int attr) {
00291 const char *caller="FEM_Mesh_get_width";
00292 FEMAPI(caller);
00293 return FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->getWidth();
00294 }
00295 FORTRAN_AS_C_RETURN(int,
00296 FEM_MESH_GET_WIDTH,FEM_Mesh_get_width,fem_mesh_get_width,
00297 (int *fem_mesh,int *entity,int *attr),(*fem_mesh,*entity,*attr)
00298 )
00299
00300 CLINKAGE int
00301 FEM_Mesh_get_datatype(int fem_mesh,int entity,int attr) {
00302 const char *caller="FEM_Mesh_get_datatype";
00303 FEMAPI(caller);
00304 return FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->getDatatype();
00305 }
00306 FORTRAN_AS_C_RETURN(int,
00307 FEM_MESH_GET_DATATYPE,FEM_Mesh_get_datatype,fem_mesh_get_datatype,
00308 (int *fem_mesh,int *entity,int *attr),(*fem_mesh,*entity,*attr)
00309 )
00310
00311 CLINKAGE int
00312 FEM_Mesh_is_set(int fem_mesh)
00313 {
00314 return (FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_is_get")->isSetting())?1:0;
00315 }
00316 FORTRAN_AS_C_RETURN(int,
00317 FEM_MESH_IS_SET,FEM_Mesh_is_set,fem_mesh_is_set,
00318 (int *fem_mesh),(*fem_mesh)
00319 )
00320
00321 CLINKAGE int
00322 FEM_Mesh_is_get(int fem_mesh)
00323 {
00324 return (!FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_is_get")->isSetting())?1:0;
00325 }
00326 FORTRAN_AS_C_RETURN(int,
00327 FEM_MESH_IS_GET,FEM_Mesh_is_get,fem_mesh_is_get,
00328 (int *fem_mesh),(*fem_mesh)
00329 )
00330
00331 CLINKAGE void
00332 FEM_Mesh_become_get(int fem_mesh)
00333 { FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_become_get")->becomeGetting(); }
00334 FORTRAN_AS_C(FEM_MESH_BECOME_GET,FEM_Mesh_become_get,fem_mesh_become_get, (int *m),(*m))
00335
00336 CLINKAGE void
00337 FEM_Mesh_become_set(int fem_mesh)
00338 { FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_become_get")->becomeSetting(); }
00339 FORTRAN_AS_C(FEM_MESH_BECOME_SET,FEM_Mesh_become_set,fem_mesh_become_set, (int *m),(*m))
00340
00341
00342 CLINKAGE IDXL_t
00343 FEM_Comm_shared(int fem_mesh,int entity) {
00344 const char *caller="FEM_Comm_shared";
00345 FEMAPI(caller);
00346 if (entity!=FEM_NODE) FEM_Abort(caller,"Only shared nodes supported");
00347 return FEM_Mesh_lookup(fem_mesh,caller)->node.
00348 sharedIDXL.getIndex(IDXL_Chunk::get(caller));
00349 }
00350 FORTRAN_AS_C_RETURN(int,
00351 FEM_COMM_SHARED,FEM_Comm_shared,fem_comm_shared,
00352 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00353 )
00354
00355 CLINKAGE IDXL_t
00356 FEM_Comm_ghost(int fem_mesh,int entity) {
00357 const char *caller="FEM_Comm_ghost";
00358 FEMAPI(caller);
00359 FEM_Entity *e=FEM_Entity_lookup(fem_mesh,entity,caller);
00360 if (e->isGhost()) FEM_Abort(caller,"Can only call FEM_Comm_ghost on real entity type");
00361 return e->ghostIDXL.getIndex(IDXL_Chunk::get(caller));
00362 }
00363 FORTRAN_AS_C_RETURN(int,
00364 FEM_COMM_GHOST,FEM_Comm_ghost,fem_comm_ghost,
00365 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00366 )
00367
00368
00369
00370 void FEM_Mesh_data_layout(int fem_mesh,int entity,int attr,
00371 void *data, int firstItem,int length, const IDXL_Layout &layout)
00372 {
00373 if (femVersion == 0 && length==0) return;
00374 const char *caller="FEM_Mesh_data";
00375 FEMAPI(caller);
00376 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00377 FEM_Attribute *a=m->lookup(entity,caller)->lookup(attr,caller);
00378
00379 if (m->isSetting())
00380 a->set(data,firstItem,length,layout,caller);
00381 else
00382 a->get(data,firstItem,length,layout,caller);
00383 }
00384
00386 void FEM_Register_array_layout(int fem_mesh,int entity,int attr,void *data,int firstItem,const IDXL_Layout &layout){
00387 const char *caller="FEM_Register_array";
00388 FEMAPI(caller);
00389 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00390 FEM_Entity *e = m->lookup(entity,caller);
00391 int length = e->size();
00392
00393 int max = e->getMax();
00394 FEM_Attribute *a = e->lookup(attr,caller);
00395
00396
00397 if(m->isSetting()){
00398 }else{
00399 a->get(data,firstItem,length,layout,caller);
00400 }
00401
00402 a->register_data(data,length,max,layout,caller);
00403 }
00404 void FEM_Register_entity_impl(int fem_mesh,int entity,void *args,int len,int max,FEM_Mesh_alloc_fn fn){
00405 const char *caller = "FEM_Register_entity";
00406 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00407
00408
00409
00410
00411 FEM_Entity *e = m->lookup(entity,caller);
00412 e->setMaxLength(len,max,args,fn);
00413 }
00414
00415 FEM_Entity *FEM_Entity_lookup(int fem_mesh,int entity,const char *caller) {
00416 return FEM_Mesh_lookup(fem_mesh,caller)->lookup(entity,caller);
00417 }
00418 FEM_Attribute *FEM_Attribute_lookup(int fem_mesh,int entity,int attr,const char *caller) {
00419 return FEM_Entity_lookup(fem_mesh,entity,caller)->lookup(attr,caller);
00420 }
00421
00422 CLINKAGE int FEM_Mesh_get_entities(int fem_mesh, int *entities) {
00423 const char *caller="FEM_Mesh_get_entities";
00424 FEMAPI(caller);
00425 return FEM_Mesh_lookup(fem_mesh,caller)->getEntities(entities);
00426 }
00427 FORTRAN_AS_C_RETURN(int,
00428 FEM_MESH_GET_ENTITIES,FEM_Mesh_get_entities,fem_mesh_get_entities,
00429 (int *mesh,int *ent), (*mesh,ent)
00430 )
00431
00432 CLINKAGE int FEM_Mesh_get_attributes(int fem_mesh,int entity,int *attributes) {
00433 const char *caller="FEM_Mesh_get_attributes";
00434 FEMAPI(caller);
00435 return FEM_Entity_lookup(fem_mesh,entity,caller)->getAttrs(attributes);
00436 }
00437 FORTRAN_AS_C_RETURN(int,
00438 FEM_MESH_GET_ATTRIBUTES,FEM_Mesh_get_attributes,fem_mesh_get_attributes,
00439 (int *mesh,int *ent,int *attrs), (*mesh,*ent,attrs)
00440 )
00441
00442
00443
00444 CLINKAGE const char *FEM_Get_datatype_name(int datatype,char *storage) {
00445 switch(datatype) {
00446 case FEM_BYTE: return "FEM_BYTE";
00447 case FEM_INT: return "FEM_INT";
00448 case FEM_FLOAT: return "FEM_FLOAT";
00449 case FEM_DOUBLE: return "FEM_DOUBLE";
00450 case FEM_INDEX_0: return "FEM_INDEX_0";
00451 case FEM_INDEX_1: return "FEM_INDEX_1";
00452 };
00453 sprintf(storage,"unknown datatype code (%d)",datatype);
00454 return storage;
00455 }
00456
00459 CLINKAGE const char *FEM_Get_attr_name(int attr,char *storage)
00460 {
00461 if (attr<FEM_ATTRIB_TAG_MAX)
00462 {
00463 sprintf(storage,"FEM_DATA+%d",attr-FEM_DATA);
00464 return storage;
00465 }
00466 switch(attr) {
00467 case FEM_CONN: return "FEM_CONN";
00468 case FEM_SPARSE_ELEM: return "FEM_SPARSE_ELEM";
00469 case FEM_COOR: return "FEM_COOR";
00470 case FEM_GLOBALNO: return "FEM_GLOBALNO";
00471 case FEM_PARTITION: return "FEM_PARTITION";
00472 case FEM_SYMMETRIES: return "FEM_SYMMETRIES";
00473 case FEM_NODE_PRIMARY: return "FEM_NODE_PRIMARY";
00474 case FEM_NODE_ELEM_ADJACENCY: return "FEM_NODE_ELEM_ADJACENCY";
00475 case FEM_NODE_NODE_ADJACENCY: return "FEM_NODE_NODE_ADJACENCY";
00476 case FEM_ELEM_ELEM_ADJACENCY: return "FEM_ELEM_ELEM_ADJACENCY";
00477 case FEM_ELEM_ELEM_ADJ_TYPES: return "FEM_ELEM_ELEM_ADJ_TYPES";
00478 case FEM_IS_VALID_ATTR: return "FEM_IS_VALID_ATTR";
00479 case FEM_MESH_SIZING: return "FEM_MESH_SIZING";
00480
00481 default: break;
00482 };
00483 sprintf(storage,"unknown attribute code (%d)",attr);
00484 return storage;
00485 }
00486
00487
00488
00489 void FEM_Attribute::bad(const char *field,bool forRead,int cur,int next,const char *caller) const
00490 {
00491 char nameStorage[256];
00492 const char *name=FEM_Get_attr_name(attr,nameStorage);
00493 char errBuf[1024];
00494 const char *cannotBe=NULL;
00495 if (forRead) {
00496 if (cur==-1) {
00497 sprintf(errBuf,"The %s %s %s was never set-- it cannot now be read",
00498 e->getName(),name,field);
00499 }
00500 else
00501 cannotBe="read as";
00502 }
00503 else {
00504 cannotBe="set to";
00505 }
00506 if (cannotBe!=NULL)
00507 sprintf(errBuf,"The %s %s %s was previously set to %d; it cannot now be %s %d",
00508 e->getName(),name,field,cur,cannotBe,next);
00509
00510 FEM_Abort(caller,errBuf);
00511 }
00512
00513
00514 FEM_Attribute::FEM_Attribute(FEM_Entity *e_,int attr_)
00515 :e(e_),ghost(0),attr(attr_),width(0),datatype(-1), allocated(false)
00516 {
00517 tryAllocate();
00518 if (femVersion == 0) width=-1;
00519 }
00520 void FEM_Attribute::pup(PUP::er &p) {
00521
00522 p|width;
00523 if (p.isUnpacking() && femVersion > 0 && width<0) width=0;
00524 p|datatype;
00525 if (p.isUnpacking()) tryAllocate();
00526 }
00527 void FEM_Attribute::pupSingle(PUP::er &p, int pupindx) {
00528
00529 p|width;
00530 if (p.isUnpacking() && femVersion > 0 && width<0) width=0;
00531 p|datatype;
00532 if (p.isUnpacking()) tryAllocate();
00533 }
00534 FEM_Attribute::~FEM_Attribute() {}
00535
00536 void FEM_Attribute::setLength(int next,const char *caller) {
00537 int cur=getLength();
00538 if (next==cur) return;
00539 if (cur>0) bad("length",false,cur,next, caller);
00540 e->setLength(next);
00541 tryAllocate();
00542 }
00543
00544 void FEM_Attribute::setWidth(int next,const char *caller) {
00545 int cur=getWidth();
00546 if (next==cur) return;
00547 if (cur>0) bad("width",false,cur,next, caller);
00548 width=next;
00549 tryAllocate();
00550 if (ghost) ghost->setWidth(width,caller);
00551 }
00552
00553 void FEM_Attribute::setDatatype(int next,const char *caller) {
00554 int cur=getDatatype();
00555 if (next==cur) return;
00556 if (cur!=-1) bad("datatype",false,cur,next, caller);
00557 datatype=next;
00558 tryAllocate();
00559 if (ghost) ghost->setDatatype(datatype,caller);
00560 }
00561
00562 void FEM_Attribute::copyShape(const FEM_Attribute &src) {
00563 setWidth(src.getWidth());
00564 if (src.getDatatype()!=-1)
00565 setDatatype(src.getDatatype());
00566 }
00567 void FEM_Attribute::set(const void *src, int firstItem,int length,
00568 const IDXL_Layout &layout, const char *caller)
00569 {
00570 if (firstItem!=0) {
00571 if (length!=1)
00572 CmiAbort("FEM_Mesh_data: unexpected firstItem");
00573 }
00574
00575 if (femVersion == 0 && getRealLength() == -1) setLength(length);
00576 else if (getLength()==0) setLength(length);
00577 else if (length!=1 && length!=getLength())
00578 bad("length",false,getLength(),length, caller);
00579
00580 int width=layout.width;
00581 if (femVersion==0 && getRealWidth()==-1) setWidth(width);
00582 else if (getWidth()==0) setWidth(width);
00583 else if (width!=getWidth())
00584 bad("width",false,getWidth(),width, caller);
00585
00586 int datatype=layout.type;
00587 if (getDatatype()==-1) setDatatype(datatype);
00588 else if (datatype!=getDatatype())
00589 bad("datatype",false,getDatatype(),datatype, caller);
00590
00591
00592
00593 }
00594
00595 void FEM_Attribute::get(void *dest, int firstItem,int length,
00596 const IDXL_Layout &layout, const char *caller) const
00597 {
00598 if (length==0) return;
00599 if (length!=1 && length!=getLength())
00600 bad("length",true,getLength(),length, caller);
00601
00602 int width=layout.width;
00603 if (width!=getWidth())
00604 bad("width",true,getWidth(),width, caller);
00605
00606 int datatype=layout.type;
00607 if (datatype!=getDatatype())
00608 bad("datatype",true,getDatatype(),datatype, caller);
00609
00610
00611 }
00612
00613
00614
00615 void FEM_Attribute::register_data(void *user, int length,int max,
00616 const IDXL_Layout &layout, const char *caller){
00617
00618 int width=layout.width;
00619 if (femVersion == 0 && getRealWidth()==-1) setWidth(width);
00620 else if (getWidth()==0){
00621 setWidth(width);
00622 }else{
00623 if (width!=getWidth()){
00624 bad("width",false,getWidth(),width, caller);
00625 }
00626 }
00627
00628 int datatype=layout.type;
00629 if (getDatatype()==-1){
00630 setDatatype(datatype);
00631 }else{
00632 if (datatype!=getDatatype()){
00633 bad("datatype",false,getDatatype(),datatype, caller);
00634 }
00635 }
00636
00637 }
00638
00639
00640
00641 void FEM_Attribute::tryAllocate(void) {
00642 int lenNull, widthNull;
00643 if (femVersion == 0) {
00644
00645 lenNull = (getRealLength()==-1);
00646 widthNull = (getRealWidth()==-1);
00647 }
00648 else {
00649 lenNull = (getLength()==0);
00650 widthNull = (getWidth()==0);
00651 }
00652 if ((!allocated) && !lenNull && !widthNull && getDatatype()!=-1) {
00653 allocated=true;
00654 allocate(getMax(),getWidth(),getDatatype());
00655 }
00656 }
00657
00658
00659 FEM_DataAttribute::FEM_DataAttribute(FEM_Entity *e,int myAttr)
00660 :FEM_Attribute(e,myAttr),
00661 char_data(0),int_data(0),float_data(0),double_data(0)
00662 {
00663 }
00664 void FEM_DataAttribute::pup(PUP::er &p) {
00665 super::pup(p);
00666 switch(getDatatype()) {
00667 case -1: break;
00668 case FEM_BYTE: if (char_data) char_data->pup(p); break;
00669 case FEM_INT: if (int_data) int_data->pup(p); break;
00670 case FEM_FLOAT: if (float_data) float_data->pup(p); break;
00671 case FEM_DOUBLE: if (double_data) double_data->pup(p); break;
00672 default: CkAbort("Invalid datatype in FEM_DataAttribute::pup");
00673 }
00674 }
00675 void FEM_DataAttribute::pupSingle(PUP::er &p, int pupindx) {
00676 super::pupSingle(p,pupindx);
00677 switch(getDatatype()) {
00678 case -1: break;
00679 case FEM_BYTE: if (char_data) char_data->pupSingle(p,pupindx); break;
00680 case FEM_INT: if (int_data) int_data->pupSingle(p,pupindx); break;
00681 case FEM_FLOAT: if (float_data) float_data->pupSingle(p,pupindx); break;
00682 case FEM_DOUBLE: if (double_data) double_data->pupSingle(p,pupindx); break;
00683 default: CkAbort("Invalid datatype in FEM_DataAttribute::pupSingle");
00684 }
00685 }
00686 FEM_DataAttribute::~FEM_DataAttribute() {
00687 if (char_data) delete char_data;
00688 if (int_data) delete int_data;
00689 if (float_data) delete float_data;
00690 if (double_data) delete double_data;
00691
00692 }
00693
00695 template <class T>
00696 inline void setTableData(const void *user, int firstItem, int length,
00697 IDXL_LAYOUT_PARAM, AllocTable2d<T> *table)
00698 {
00699 for (int r=0;r<length;r++) {
00700 T *tableRow=table->getRow(firstItem+r);
00701 for (int c=0;c<width;c++)
00702 tableRow[c]=IDXL_LAYOUT_DEREF(T,user,r,c);
00703 }
00704 }
00705
00707 template <class T>
00708 inline void getTableData(void *user, int firstItem, int length,
00709 IDXL_LAYOUT_PARAM, const AllocTable2d<T> *table)
00710 {
00711 for (int r=0;r<length;r++) {
00712 const T *tableRow=table->getRow(firstItem+r);
00713 for (int c=0;c<width;c++)
00714 IDXL_LAYOUT_DEREF(T,user,r,c)=tableRow[c];
00715 }
00716
00717 }
00718
00719 void FEM_DataAttribute::set(const void *u, int f,int l,
00720 const IDXL_Layout &layout, const char *caller)
00721 {
00722 super::set(u,f,l,layout,caller);
00723 switch(getDatatype()) {
00724 case FEM_BYTE: setTableData(u,f,l,IDXL_LAYOUT_CALL(layout),char_data); break;
00725 case FEM_INT: setTableData(u,f,l,IDXL_LAYOUT_CALL(layout),int_data); break;
00726 case FEM_FLOAT: setTableData(u,f,l,IDXL_LAYOUT_CALL(layout),float_data); break;
00727 case FEM_DOUBLE: setTableData(u,f,l,IDXL_LAYOUT_CALL(layout),double_data); break;
00728 }
00729 }
00730
00731 void FEM_DataAttribute::get(void *u, int f,int l,
00732 const IDXL_Layout &layout, const char *caller) const
00733 {
00734 super::get(u,f,l,layout,caller);
00735 switch(getDatatype()) {
00736 case FEM_BYTE: getTableData(u,f,l,IDXL_LAYOUT_CALL(layout),char_data); break;
00737 case FEM_INT: getTableData(u,f,l,IDXL_LAYOUT_CALL(layout),int_data); break;
00738 case FEM_FLOAT: getTableData(u,f,l,IDXL_LAYOUT_CALL(layout),float_data); break;
00739 case FEM_DOUBLE: getTableData(u,f,l,IDXL_LAYOUT_CALL(layout),double_data); break;
00740 }
00741 }
00742
00743 void FEM_DataAttribute::register_data(void *u,int l,int max,
00744 const IDXL_Layout &layout, const char *caller)
00745 {
00746 super::register_data(u,l,max,layout,caller);
00747 switch(getDatatype()){
00748 case FEM_BYTE: char_data->register_data((unsigned char *)u,l,max); break;
00749 case FEM_INT: int_data->register_data((int *)u,l,max); break;
00750 case FEM_FLOAT: float_data->register_data((float *)u,l,max);break;
00751 case FEM_DOUBLE: double_data->register_data((double *)u,l,max);break;
00752 }
00753 }
00754
00755 template<class T>
00756 inline AllocTable2d<T> *allocTablePtr(AllocTable2d<T> *src,int len,int wid) {
00757 if (src==NULL) src=new AllocTable2d<T>;
00758 src->allocate(wid,len);
00759 return src;
00760 }
00761 void FEM_DataAttribute::allocate(int l,int w,int datatype)
00762 {
00763 switch(datatype) {
00764 case FEM_BYTE: char_data=allocTablePtr(char_data,l,w); break;
00765 case FEM_INT: int_data=allocTablePtr(int_data,l,w); break;
00766 case FEM_FLOAT: float_data=allocTablePtr(float_data,l,w); break;
00767 case FEM_DOUBLE: double_data=allocTablePtr(double_data,l,w); break;
00768 default: CkAbort("Invalid datatype in FEM_DataAttribute::allocate");
00769 };
00770 }
00771 void FEM_DataAttribute::copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity)
00772 {
00773 const FEM_DataAttribute *dsrc=(const FEM_DataAttribute *)&src;
00774 switch(getDatatype()) {
00775 case FEM_BYTE: char_data->setRow(dstEntity,dsrc->char_data->getRow(srcEntity)); break;
00776 case FEM_INT:
00777 int_data->setRow(dstEntity,dsrc->int_data->getRow(srcEntity)); break;
00778 case FEM_FLOAT: float_data->setRow(dstEntity,dsrc->float_data->getRow(srcEntity)); break;
00779 case FEM_DOUBLE: double_data->setRow(dstEntity,dsrc->double_data->getRow(srcEntity)); break;
00780 }
00781 }
00782
00783 template<class T>
00784 inline void interpolateAttrs(AllocTable2d<T> *data,int A,int B,int D,double frac,int width){
00785 T *rowA = data->getRow(A);
00786 T *rowB = data->getRow(B);
00787 T *rowD = data->getRow(D);
00788 for(int i=0;i<width;i++){
00789 double val = (double )rowA[i];
00790 val *= (frac);
00791 val += (1-frac) *((double )rowB[i]);
00792 rowD[i] = (T )val;
00793 }
00794 }
00795
00796 template<class T>
00797 inline void interpolateAttrs(AllocTable2d<T> *data,int *iNodes,int rNode,int k,int width){
00798 T *row[8];
00799 for (int i=0; i<k; i++) {
00800 row[i] = data->getRow(iNodes[i]);
00801 }
00802 T *rowR = data->getRow(rNode);
00803 for(int i=0;i<width;i++){
00804 double val = 0.0;
00805 for (int j=0; j<k; j++) {
00806 val += (double)row[j][i];
00807 }
00808 val = val/k;
00809 rowR[i] = (T )val;
00810 }
00811 }
00812
00813 template<class T>
00814 inline void minAttrs(AllocTable2d<T> *data,int A,int B,int D,double frac,int width){
00815 T *rowA = data->getRow(A);
00816 T *rowB = data->getRow(B);
00817 T *rowD = data->getRow(D);
00818 for(int i=0;i<width;i++){
00819 if(rowA[i] < rowB[i]){
00820 rowD[i] = rowA[i];
00821 }else{
00822 rowD[i] = rowB[i];
00823 }
00824 }
00825 }
00826
00827 template<class T>
00828 inline void minAttrs(AllocTable2d<T> *data,int *iNodes,int rNode,int k,int width){
00829 T *row[8];
00830 for (int i=0; i<k; i++) {
00831 row[i] = data->getRow(iNodes[i]);
00832 }
00833 T *rowR = data->getRow(rNode);
00834 for(int i=0;i<width;i++){
00835 rowR[i] = row[0][i];
00836 for (int j=1; j<k; j++) {
00837 if (row[j][i] < rowR[i]) {
00838 rowR[i] = row[j][i];
00839 }
00840 }
00841 }
00842 }
00843
00844 void FEM_DataAttribute::interpolate(int A,int B,int D,double frac){
00845 switch(getDatatype()){
00846 case FEM_BYTE:
00847 minAttrs(char_data,A,B,D,frac,getWidth());
00848 break;
00849 case FEM_INT:
00850 minAttrs(int_data,A,B,D,frac,getWidth());
00851 break;
00852 case FEM_FLOAT:
00853 interpolateAttrs(float_data,A,B,D,frac,getWidth());
00854 break;
00855 case FEM_DOUBLE:
00856 interpolateAttrs(double_data,A,B,D,frac,getWidth());
00857 break;
00858 }
00859 }
00860
00861 void FEM_DataAttribute::interpolate(int *iNodes,int rNode,int k){
00862 switch(getDatatype()){
00863 case FEM_BYTE:
00864 minAttrs(char_data,iNodes,rNode,k,getWidth());
00865 break;
00866 case FEM_INT:
00867 minAttrs(int_data,iNodes,rNode,k,getWidth());
00868 break;
00869 case FEM_FLOAT:
00870 interpolateAttrs(float_data,iNodes,rNode,k,getWidth());
00871 break;
00872 case FEM_DOUBLE:
00873 interpolateAttrs(double_data,iNodes,rNode,k,getWidth());
00874 break;
00875 }
00876 }
00877
00878
00879 FEM_IndexAttribute::Checker::~Checker() {}
00880
00881 FEM_IndexAttribute::FEM_IndexAttribute(FEM_Entity *e,int myAttr,FEM_IndexAttribute::Checker *checker_)
00882 :FEM_Attribute(e,myAttr), idx(0,0,-1), checker(checker_)
00883 {
00884 setDatatype(FEM_INT);
00885 }
00886 void FEM_IndexAttribute::pup(PUP::er &p) {
00887 super::pup(p);
00888 p|idx;
00889 }
00890 void FEM_IndexAttribute::pupSingle(PUP::er &p, int pupindx) {
00891 super::pupSingle(p,pupindx);
00892 idx.pupSingle(p,pupindx);
00893 }
00894 FEM_IndexAttribute::~FEM_IndexAttribute() {
00895 if (checker) delete checker;
00896 }
00897
00898 void FEM_IndexAttribute::allocate(int length,int width,int datatype)
00899 {
00900 idx.allocate(width,length);
00901 }
00902
00908 static int type2base(int base_type,const char *caller) {
00909 if (base_type==FEM_INDEX_0) return 0;
00910 if (base_type==FEM_INDEX_1) return 1;
00911 FEM_Abort(caller,"You must use the datatype FEM_INDEX_0 or FEM_INDEX_1 with FEM_CONN, not %d",
00912 base_type);
00913 return 0;
00914 }
00915
00917 void setIndexTableData(const void *user, int firstItem, int length,
00918 IDXL_LAYOUT_PARAM, AllocTable2d<int> *table,int indexBase)
00919 {
00920 for (int r=0;r<length;r++) {
00921 int *tableRow=table->getRow(firstItem+r);
00922 for (int c=0;c<width;c++)
00923 tableRow[c]=IDXL_LAYOUT_DEREF(int,user,r,c)-indexBase;
00924 }
00925 }
00926
00928 void getIndexTableData(void *user, int firstItem, int length,
00929 IDXL_LAYOUT_PARAM, const AllocTable2d<int> *table,int indexBase)
00930 {
00931 for (int r=0;r<length;r++) {
00932 const int *tableRow=table->getRow(firstItem+r);
00933 for (int c=0;c<width;c++)
00934 IDXL_LAYOUT_DEREF(int,user,r,c)=tableRow[c]+indexBase;
00935 }
00936 }
00937
00938 void FEM_IndexAttribute::set(const void *src, int firstItem,int length,
00939 const IDXL_Layout &layout,const char *caller)
00940 {
00941 IDXL_Layout lo=layout; lo.type=FEM_INT;
00942 super::set(src,firstItem,length,lo,caller);
00943
00944 int indexBase=type2base(layout.type,caller);
00945 setIndexTableData(src,firstItem,length,IDXL_LAYOUT_CALL(layout),&idx,indexBase);
00946
00947 if (checker)
00948 for (int r=0;r<length;r++)
00949 checker->check(firstItem+r,idx,caller);
00950 }
00951
00952 void FEM_IndexAttribute::get(void *dest, int firstItem,int length,
00953 const IDXL_Layout &layout,const char *caller) const
00954 {
00955 IDXL_Layout lo=layout; lo.type=FEM_INT;
00956 super::get(dest,firstItem,length,lo,caller);
00957
00958 int indexBase=type2base(layout.type,caller);
00959 getIndexTableData(dest,firstItem,length,IDXL_LAYOUT_CALL(layout),&idx,indexBase);
00960 }
00961
00962 void FEM_IndexAttribute::register_data(void *user, int length,int max,
00963 const IDXL_Layout &layout, const char *caller){
00964 IDXL_Layout lo=layout; lo.type=FEM_INT;
00965 super::register_data(user,length,max,lo,caller);
00966
00967 idx.register_data((int *)user,length,max);
00968 }
00969
00970 void FEM_IndexAttribute::copyEntity(int dstEntity,const FEM_Attribute &src,int srcEntity)
00971 {
00972 const FEM_IndexAttribute *csrc=(const FEM_IndexAttribute *)&src;
00973 idx.setRow(dstEntity,csrc->idx.getRow(srcEntity));
00974 }
00975
00976
00977
00978 FEM_VarIndexAttribute::FEM_VarIndexAttribute(FEM_Entity *e,int myAttr)
00979 :FEM_Attribute(e,myAttr)
00980 {
00981 oldlength = 0;
00982 allocate(getMax(),getWidth(),getDatatype());
00983 setDatatype(FEM_INT);
00984 }
00985
00986 void FEM_VarIndexAttribute::pup(PUP::er &p){
00987 super::pup(p);
00988 p | idx;
00989 }
00990
00991 void FEM_VarIndexAttribute::pupSingle(PUP::er &p, int pupindx){
00992 super::pupSingle(p,pupindx);
00993 p|idx[pupindx];
00994 }
00995
00996 void FEM_VarIndexAttribute::set(const void *src,int firstItem,int length,
00997 const IDXL_Layout &layout,const char *caller){
00998 printf("set not yet implemented for FEM_VarIndexAttribute \n");
00999 }
01000
01001 void FEM_VarIndexAttribute::get(void *dest, int firstItem,int length,
01002 const IDXL_Layout &layout, const char *caller) const{
01003 printf("get not yet implemented for FEM_VarIndexAttribute \n");
01004
01005 }
01006
01007 void FEM_VarIndexAttribute::copyEntity(int dstEntity,const FEM_Attribute &_src,int srcEntity){
01008 FEM_VarIndexAttribute &src = (FEM_VarIndexAttribute &)_src;
01009 const CkVec<CkVec<ID> > &srcTable = src.get();
01010 idx.insert(dstEntity,srcTable[srcEntity]);
01011 }
01012
01013 void FEM_VarIndexAttribute::print(){
01014 for(int i=0;i<idx.size();i++){
01015 printf("%d -> ",i);
01016 for(int j=0;j<idx[i].size();j++){
01017 printf("(%d %d) ",((idx[i])[j]).type,((idx[i])[j]).id);
01018 }
01019 printf("\n");
01020 }
01021 }
01022
01023 int FEM_VarIndexAttribute::findInRow(int row,const ID &data){
01024 if(row >= idx.length()){
01025 return -1;
01026 }
01027 CkVec<ID> &rowVec = idx[row];
01028 for(int i=0;i<rowVec.length();i++){
01029 if(data == rowVec[i]){
01030 return i;
01031 }
01032 }
01033 return -1;
01034 }
01035
01036
01037
01039 CLINKAGE const char *FEM_Get_entity_name(int entity,char *storage)
01040 {
01041 char *dest=storage;
01042 if (entity<FEM_ENTITY_FIRST || entity>=FEM_ENTITY_LAST) {
01043 sprintf(dest,"unknown entity code (%d)",entity);
01044 }
01045 else {
01046 if (entity>FEM_ENTITY_FIRST+FEM_GHOST) {
01047 sprintf(dest,"FEM_GHOST+");
01048 dest+=strlen(dest);
01049 entity-=FEM_GHOST;
01050 }
01051 if (entity==FEM_NODE)
01052 sprintf(dest,"FEM_NODE");
01053 else if (entity>=FEM_SPARSE)
01054 sprintf(dest,"FEM_SPARSE+%d",entity-FEM_SPARSE);
01055 else
01056 sprintf(dest,"FEM_ELEM+%d",entity-FEM_ELEM);
01057 }
01058 return storage;
01059 }
01060
01061 FEM_Entity::FEM_Entity(FEM_Entity *ghost_)
01062 :length(0), max(0),ghost(ghost_), coord(0), sym(0), globalno(0), valid(0), meshSizing(0),
01063 ghostIDXL(ghost?&ghostSend:NULL, ghost?&ghost->ghostRecv:NULL),resize(NULL)
01064 {
01065
01066 if (femVersion == 0) {
01067 length=-1;
01068 max=-1;
01069 }
01070 }
01071 void FEM_Entity::pup(PUP::er &p) {
01072 p|length;
01073 if (p.isUnpacking() && femVersion > 0 && length<0) length=0;
01074 p.comment(" Ghosts to send out: ");
01075 ghostSend.pup(p);
01076 p.comment(" Ghosts to recv: ");
01077 ghostRecv.pup(p);
01078 p.comment(" Ghost IDXL tag: ");
01079 ghostIDXL.pup(p);
01080
01081 int nAttributes=attributes.size();
01082 p|nAttributes;
01083 for (int a=0;a<nAttributes;a++)
01084 {
01085
01086
01087
01088
01089
01090
01091
01092 int attr=0;
01093 FEM_Attribute *r=NULL;
01094 if (!p.isUnpacking()) {
01095 r=attributes[a];
01096 attr=r->getAttr();
01097 }
01098 p|attr;
01099 if (p.isUnpacking()) {
01100 r=lookup(attr,"FEM_Entity::pup");
01101 }
01102
01103 {
01104 char attrNameStorage[256];
01105 p.comment(FEM_Get_attr_name(attr,attrNameStorage));
01106 }
01107
01108 r->pup(p);
01109 }
01110
01111 if (ghost!=NULL) {
01112 p.comment(" ---- Ghost attributes ---- ");
01113 ghost->pup(p);
01114 }
01115 }
01116 FEM_Entity::~FEM_Entity()
01117 {
01118 delete ghost;
01119 for (int a=0;a<attributes.size();a++)
01120 delete attributes[a];
01121 }
01122
01124 void FEM_Entity::copyShape(const FEM_Entity &src) {
01125 for (int a=0;a<src.attributes.size();a++)
01126 {
01127 const FEM_Attribute *Asrc=src.attributes[a];
01128 FEM_Attribute *Adst=lookup(Asrc->getAttr(),"FEM_Entity::copyShape");
01129 Adst->copyShape(*Asrc);
01130 }
01131 if (ghost) ghost->copyShape(*src.ghost);
01132 }
01133
01134 void FEM_Entity::setLength(int newlen)
01135 {
01136 if (!resize) {
01137 if (size() != newlen) {
01138 length = newlen;
01139
01140 for (int a=0; a<attributes.size(); a++) {
01141 CkAssert(attributes[a]->getWidth() < 1000);
01142 attributes[a]->reallocate();
01143 }
01144 }
01145 }
01146 else {
01147 length = newlen;
01148 if (length > max) {
01149 if (max > 4) {
01150 max = max + (max >> 2);
01151 }
01152 else {
01153 max = max + 10;
01154 }
01155 for (int a=0;a<attributes.size();a++){
01156 int code = attributes[a]->getAttr();
01157 if(!(code <= FEM_ATTRIB_TAG_MAX || code == FEM_CONN || code == FEM_BOUNDARY)){
01158 attributes[a]->reallocate();
01159 }
01160 }
01161
01162 CkPrintf("Resize called \n");
01163 resize(args,&length,&max);
01164 }
01165 }
01166 }
01167
01168 void FEM_Entity::allocateValid(void) {
01169 if (!valid){
01170 valid=new FEM_DataAttribute(this,FEM_IS_VALID_ATTR);
01171 add(valid);
01172 valid->setWidth(1);
01173 valid->setLength(size());
01174 valid->setDatatype(FEM_BYTE);
01175 valid->reallocate();
01176
01177
01178 for(int i=0;i<size();i++)
01179 valid->getChar()(i,0)=1;
01180 first_invalid = last_invalid = 0;
01181 }
01182
01183 }
01184
01185 void FEM_Entity::set_valid(unsigned int idx, bool isNode){
01186 if(false) {
01187 CkAssert(idx < size() && idx >=0);
01188 valid->getChar()(idx,0)=1;
01189 }
01190 else {
01191 CkAssert(idx < size() && idx >=0 && first_invalid<=last_invalid);
01192 valid->getChar()(idx,0)=1;
01193
01194 if(idx == first_invalid)
01195
01196 while((first_invalid<last_invalid) && is_valid(first_invalid)){
01197 first_invalid++;
01198 }
01199 else if(idx == last_invalid)
01200
01201 while((first_invalid<last_invalid) && is_valid(last_invalid))
01202 last_invalid--;
01203
01204
01205 if( first_invalid == last_invalid && is_valid(first_invalid) )
01206 first_invalid = last_invalid = 0;
01207 }
01208 }
01209
01210 void FEM_Entity::set_invalid(unsigned int idx, bool isNode){
01211 if(false) {
01212 CkAssert(idx < size() && idx >=0);
01213 valid->getChar()(idx,0)=0;
01214 }
01215 else {
01216 CkAssert(idx < size() && idx >=0 && first_invalid<=last_invalid);
01217 valid->getChar()(idx,0)=0;
01218
01219
01220 if(first_invalid==0 && last_invalid==0 && is_valid(0)){
01221 first_invalid = last_invalid = idx;
01222 return;
01223 }
01224
01225 if(idx < first_invalid){
01226 first_invalid = idx;
01227 }
01228
01229 if(idx > last_invalid){
01230 last_invalid = idx;
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242 }
01243 }
01244
01245 int FEM_Entity::is_valid(unsigned int idx){
01246 if(false) {
01247 CkAssert(idx < size() && idx >=0);
01248 return valid->getChar()(idx,0);
01249 } else {
01250 CkAssert(idx < size() && idx >=0 && first_invalid<=last_invalid);
01251 return valid->getChar()(idx,0);
01252 }
01253 }
01254
01255 unsigned int FEM_Entity::count_valid(){
01256 CkAssert(first_invalid<=last_invalid);
01257 unsigned int count=0;
01258 for(int i=0;i<size();i++)
01259 if(is_valid(i)) count++;
01260 return count;
01261 }
01262
01267 unsigned int FEM_Entity::get_next_invalid(FEM_Mesh *m, bool isNode, bool isGhost){
01268 unsigned int retval;
01269 if(false) {
01270 retval = size();
01271 setLength(retval+1);
01272 }
01273 else {
01274 CkAssert(!is_valid(first_invalid) || first_invalid==0);
01275
01276
01277 bool flag1 = false;
01278 if(!is_valid(first_invalid)){
01279 retval = first_invalid;
01280 if(isNode && !isGhost) {
01281 while(retval <= last_invalid) {
01282 if(!is_valid(retval)) {
01283 if(m->getfmMM()->fmLockN[retval]->haslocks()) {
01284 retval++;
01285 }
01286 else if(hasConn(retval)) {
01287 retval++;
01288 }
01289 else {
01290 flag1 = true;
01291 break;
01292 }
01293 }
01294 else retval++;
01295 }
01296 }
01297 else if(isNode) {
01298 while(retval <= last_invalid) {
01299 if(!is_valid(retval)) {
01300 if(hasConn(retval)) {
01301 retval++;
01302 }
01303 else {
01304 flag1 = true;
01305 break;
01306 }
01307 }
01308 else retval++;
01309 }
01310 }
01311 else{
01312
01313 flag1 = true;
01314 }
01315 }
01316 if(!flag1) {
01317 retval = size();
01318 setLength(retval+1);
01319 }
01320 }
01321 set_valid(retval,isNode);
01322 return retval;
01323 }
01324
01325 void FEM_Entity::setMaxLength(int newLen,int newMaxLen,void *pargs,FEM_Mesh_alloc_fn fn){
01326 CkPrintf("resize fn %p \n",fn);
01327 max = newMaxLen;
01328 resize = fn;
01329 args = pargs;
01330 setLength(newLen);
01331 }
01332
01333
01335 void FEM_Entity::copyEntity(int dstEntity,const FEM_Entity &src,int srcEntity) {
01336 FEM_Entity *dp=this;
01337 const FEM_Entity *sp=&src;
01338 for (int a=0;a<sp->attributes.size();a++)
01339 {
01340 const FEM_Attribute *Asrc=sp->attributes[a];
01341 FEM_Attribute *Adst=dp->lookup(Asrc->getAttr(),"FEM_Entity::copyEntity");
01342 Adst->copyEntity(dstEntity,*Asrc,srcEntity);
01343 }
01344 }
01345
01348 int FEM_Entity::push_back(const FEM_Entity &src,int srcEntity) {
01349 int dstEntity=size();
01350 setLength(dstEntity+1);
01351 copyEntity(dstEntity,src,srcEntity);
01352 return dstEntity;
01353 }
01354
01357 void FEM_Entity::add(FEM_Attribute *attribute) {
01358 if (ghost!=NULL)
01359 {
01360 attribute->setGhost(ghost->lookup(attribute->getAttr(),"FEM_Entity::add"));
01361 }
01362 attributes.push_back(attribute);
01363 }
01364
01370 FEM_Attribute *FEM_Entity::lookup(int attr,const char *caller) {
01371
01372 for (int a=0;a<attributes.size();a++) {
01373 if (attributes[a]->getAttr()==attr)
01374 return attributes[a];
01375 }
01376
01377
01378 create(attr,caller);
01379
01380
01381 return lookup(attr,caller);
01382 }
01383
01390 void FEM_Entity::create(int attr,const char *caller) {
01391 if (attr<=FEM_ATTRIB_TAG_MAX)
01392 add(new FEM_DataAttribute(this,attr));
01393 else if (attr==FEM_COORD)
01394 allocateCoord();
01395 else if (attr==FEM_SYMMETRIES)
01396 allocateSym();
01397 else if (attr==FEM_GLOBALNO)
01398 allocateGlobalno();
01399 else if (attr==FEM_IS_VALID_ATTR)
01400 allocateValid();
01401 else if (attr==FEM_MESH_SIZING)
01402 allocateMeshSizing();
01403 else if(attr == FEM_CHUNK){
01404 FEM_IndexAttribute *chunkNo= new FEM_IndexAttribute(this,FEM_CHUNK,NULL);
01405 add(chunkNo);
01406 chunkNo->setWidth(1);
01407 } else if(attr == FEM_BOUNDARY){
01408
01409 allocateBoundary();
01410 } else {
01411
01412 char attrNameStorage[256], msg[1024];
01413 sprintf(msg,"Could not locate the attribute %s for entity %s",
01414 FEM_Get_attr_name(attr,attrNameStorage), getName());
01415 FEM_Abort(caller,msg);
01416 }
01417 }
01418
01419 void FEM_Entity::allocateCoord(void) {
01420 if (coord) CkAbort("FEM_Entity::allocateCoord called, but already allocated");
01421 coord=new FEM_DataAttribute(this,FEM_COORD);
01422 add(coord);
01423 coord->setDatatype(FEM_DOUBLE);
01424 }
01425
01426 void FEM_Entity::allocateSym(void) {
01427 if (sym) CkAbort("FEM_Entity::allocateSym called, but already allocated");
01428 sym=new FEM_DataAttribute(this,FEM_SYMMETRIES);
01429 add(sym);
01430 sym->setWidth(1);
01431 sym->setDatatype(FEM_BYTE);
01432 }
01433
01434 void FEM_Entity::setSymmetries(int r,FEM_Symmetries_t s)
01435 {
01436 if (!sym) {
01437 if (s==0) return;
01438 allocateSym();
01439 }
01440 sym->getChar()(r,0)=s;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453 inline void FEM_Entity::set_coord(int idx, double x, double y){
01454 if(coord){
01455 coord->getDouble()(idx,0)=x;
01456 coord->getDouble()(idx,1)=y;
01457 }
01458 else {
01459 FEM_DataAttribute* attr = (FEM_DataAttribute*)lookup(FEM_DATA,"set_coord");
01460 attr->getDouble()(idx,0)=x;
01461 attr->getDouble()(idx,1)=y;
01462 }
01463 }
01464
01465 inline void FEM_Entity::set_coord(int idx, double x, double y, double z){
01466 if(coord){
01467 coord->getDouble()(idx,0)=x;
01468 coord->getDouble()(idx,1)=y;
01469 coord->getDouble()(idx,2)=z;
01470 }
01471 else {
01472 FEM_DataAttribute* attr = (FEM_DataAttribute*)lookup(FEM_DATA,"set_coord");
01473 attr->getDouble()(idx,0)=x;
01474 attr->getDouble()(idx,1)=y;
01475 attr->getDouble()(idx,2)=z;
01476 }
01477 }
01478
01479
01480 void FEM_Entity::allocateGlobalno(void) {
01481 if (globalno) CkAbort("FEM_Entity::allocateGlobalno called, but already allocated");
01482 globalno=new FEM_IndexAttribute(this,FEM_GLOBALNO,NULL);
01483 add(globalno);
01484 globalno->setWidth(1);
01485 }
01486
01487 void FEM_Entity::allocateMeshSizing(void) {
01488 if (meshSizing)
01489 CkAbort("FEM_Entity::allocateMeshSizing called, but already allocated");
01490 meshSizing=new FEM_DataAttribute(this,FEM_MESH_SIZING);
01491 add(meshSizing);
01492 meshSizing->setWidth(1);
01493 meshSizing->setDatatype(FEM_DOUBLE);
01494 }
01495
01496 double FEM_Entity::getMeshSizing(int r) {
01497 if (!meshSizing) {
01498 allocateMeshSizing();
01499 return -1.0;
01500 }
01501 if (r >= 0) return meshSizing->getDouble()(r,0);
01502 else return ghost->meshSizing->getDouble()(FEM_To_ghost_index(r),0);
01503 }
01504
01505 void FEM_Entity::setMeshSizing(int r,double s)
01506 {
01507 if (!meshSizing) allocateMeshSizing();
01508 if (s <= 0.0) return;
01509 if (r >= 0) meshSizing->getDouble()(r,0)=s;
01510 else ghost->meshSizing->getDouble()(FEM_To_ghost_index(r),0)=s;
01511 }
01512
01513 void FEM_Entity::setMeshSizing(double *sf)
01514 {
01515 if (!meshSizing) allocateMeshSizing();
01516 int len = size();
01517 for (int i=0; i<len; i++)
01518 meshSizing->getDouble()(i,0)=sf[i];
01519 }
01520
01521 void FEM_Entity::allocateBoundary(){
01522 FEM_DataAttribute *bound = new FEM_DataAttribute(this,FEM_BOUNDARY);
01523 add(bound);
01524 bound->setWidth(1);
01525 bound->setDatatype(FEM_INT);
01526 }
01527
01528 void FEM_Entity::setGlobalno(int r,int g) {
01529 if (!globalno) allocateGlobalno();
01530 globalno->get()(r,0)=g;
01531 }
01532 void FEM_Entity::setAscendingGlobalno(void) {
01533 if (!globalno) {
01534 allocateGlobalno();
01535 int len=size();
01536 for (int i=0;i<len;i++) globalno->get()(i,0)=i;
01537 }
01538 }
01539 void FEM_Entity::setAscendingGlobalno(int base) {
01540 if (!globalno) {
01541 allocateGlobalno();
01542 int len=size();
01543 for (int i=0;i<len;i++) globalno->get()(i,0)=i+base;
01544 }
01545 }
01546 void FEM_Entity::copyOldGlobalno(const FEM_Entity &e) {
01547 if ((!hasGlobalno()) && e.hasGlobalno() && size()>=e.size()) {
01548 for (int i=0;i<size();i++)
01549 setGlobalno(i,e.getGlobalno(i));
01550 }
01551 }
01552
01553
01554 FEM_Node::FEM_Node(FEM_Node *ghost_)
01555 :FEM_Entity(ghost_), primary(0), sharedIDXL(&shared,&shared),
01556 elemAdjacency(0),nodeAdjacency(0)
01557 {}
01558
01559 void FEM_Node::allocatePrimary(void) {
01560 if (primary) CkAbort("FEM_Node::allocatePrimary called, but already allocated");
01561 primary=new FEM_DataAttribute(this,FEM_NODE_PRIMARY);
01562 add(primary);
01563 primary->setWidth(1);
01564 primary->setDatatype(FEM_BYTE);
01565 }
01566
01567 bool FEM_Node::hasConn(unsigned int idx) {
01568 if((elemAdjacency->get()[idx].length() > 0)||(nodeAdjacency->get()[idx].length() > 0))
01569 return true;
01570 else return false;
01571 }
01572
01573 void FEM_Node::pup(PUP::er &p) {
01574 p.comment(" ---------------- Nodes ------------------ ");
01575 super::pup(p);
01576 p.comment(" ---- Shared nodes ----- ");
01577 shared.pup(p);
01578 p.comment(" shared nodes IDXL ");
01579 sharedIDXL.pup(p);
01580 }
01581 FEM_Node::~FEM_Node() {
01582 }
01583
01584
01585 const char *FEM_Node::getName(void) const {return "FEM_NODE";}
01586
01587 void FEM_Node::create(int attr,const char *caller) {
01588 if (attr==FEM_NODE_PRIMARY)
01589 allocatePrimary();
01590 else if(attr == FEM_NODE_ELEM_ADJACENCY)
01591 allocateElemAdjacency();
01592 else if(attr == FEM_NODE_NODE_ADJACENCY)
01593 allocateNodeAdjacency();
01594 else
01595 super::create(attr,caller);
01596 }
01597
01598
01599
01601 class FEM_Elem_Conn_Checker : public FEM_IndexAttribute::Checker {
01602 const FEM_Entity &sizeSrc;
01603 const FEM_Entity *sizeSrc2;
01604 public:
01605 FEM_Elem_Conn_Checker(const FEM_Entity &sizeSrc_,const FEM_Entity *sizeSrc2_)
01606 :sizeSrc(sizeSrc_), sizeSrc2(sizeSrc2_) {}
01607
01608 void check(int row,const BasicTable2d<int> &table,const char *caller) const {
01609 const int *idx=table.getRow(row);
01610 int n=table.width();
01611 int max=sizeSrc.size();
01612 if (sizeSrc2) max+=sizeSrc2->size();
01613 for (int i=0;i<n;i++)
01614 if ((idx[i]<0) || (idx[i]>=max))
01615 {
01616 if (idx[i]<0)
01617 FEM_Abort(caller,"Connectivity entry %d's value, %d, is negative",row,idx[i]);
01618 else
01619 FEM_Abort(caller,
01620 "Connectivity entry %d's value, %d, should be less than the number of nodes, %d",
01621 row,idx[i],max);
01622 }
01623 }
01624 };
01625
01626 FEM_Elem::FEM_Elem(const FEM_Mesh &mesh, FEM_Elem *ghost_)
01627 :FEM_Entity(ghost_), elemAdjacency(0), elemAdjacencyTypes(0)
01628 {
01629 FEM_IndexAttribute::Checker *c;
01630 if (isGhost())
01631 c=new FEM_Elem_Conn_Checker(mesh.node, mesh.node.getGhost());
01632 else
01633 c=new FEM_Elem_Conn_Checker(mesh.node, NULL);
01634 conn=new FEM_IndexAttribute(this,FEM_CONN,c);
01635 add(conn);
01636 }
01637 void FEM_Elem::pup(PUP::er &p) {
01638 p.comment(" ------------- Element data ---------- ");
01639 FEM_Entity::pup(p);
01640 }
01641 FEM_Elem::~FEM_Elem() {
01642 }
01643
01644
01645 void FEM_Elem::create(int attr,const char *caller) {
01646
01647
01648
01649
01650
01651
01652
01653 if(attr == FEM_ELEM_ELEM_ADJACENCY)
01654 allocateElemAdjacency();
01655 else if(attr == FEM_ELEM_ELEM_ADJ_TYPES)
01656 allocateElemAdjacency();
01657 else
01658 super::create(attr,caller);
01659 }
01660
01661
01662 const char *FEM_Elem::getName(void) const {
01663 return "FEM_ELEM";
01664 }
01665
01666 bool FEM_Elem::hasConn(unsigned int idx) {
01667 return false;
01668 }
01669
01670
01675 class FEM_Sparse_Elem_Checker : public FEM_IndexAttribute::Checker {
01676 const FEM_Mesh &mesh;
01677 public:
01678 FEM_Sparse_Elem_Checker(const FEM_Mesh &mesh_) :mesh(mesh_) {}
01679
01680 void check(int row,const BasicTable2d<int> &table,const char *caller) const {
01681
01682 const int *elem=table.getRow(row);
01683 int maxT=mesh.elem.size();
01684 if ((elem[0]<0) || (elem[1]<0))
01685 FEM_Abort(caller,"Sparse element entry %d's values, %d and %d, are negative",
01686 row,elem[0],elem[1]);
01687 int t=elem[0];
01688 if (t>=maxT)
01689 FEM_Abort(caller,"Sparse element entry %d's element type, %d, is too big",
01690 row,elem[0]);
01691 if (elem[1]>=mesh.elem[t].size())
01692 FEM_Abort(caller,"Sparse element entry %d's element index, %d, is too big",
01693 row,elem[1]);
01694 }
01695 };
01696
01697 FEM_Sparse::FEM_Sparse(const FEM_Mesh &mesh_,FEM_Sparse *ghost_)
01698 :FEM_Elem(mesh_,ghost_), elem(0), mesh(mesh_)
01699 {
01700 }
01701 void FEM_Sparse::allocateElem(void) {
01702 if (elem) CkAbort("FEM_Sparse::allocateElem called, but already allocated");
01703 FEM_IndexAttribute::Checker *checker=new FEM_Sparse_Elem_Checker(mesh);
01704 elem=new FEM_IndexAttribute(this,FEM_SPARSE_ELEM,checker);
01705 add(elem);
01706 elem->setWidth(2);
01707 }
01708 void FEM_Sparse::pup(PUP::er &p) {
01709 p.comment(" ------------- Sparse Element ---------- ");
01710 super::pup(p);
01711 }
01712 FEM_Sparse::~FEM_Sparse() {
01713 }
01714
01715 const char *FEM_Sparse::getName(void) const { return "FEM_SPARSE"; }
01716
01717 void FEM_Sparse::create(int attr,const char *caller) {
01718 if (attr==FEM_SPARSE_ELEM)
01719 allocateElem();
01720 else FEM_Entity::create(attr,caller);
01721 }
01722
01723
01724
01725 FEM_Mesh::FEM_Mesh()
01726 :node(new FEM_Node(NULL)),
01727 elem(*this,"FEM_ELEM"),
01728 sparse(*this,"FEM_SPARSE"),
01729 lastElemAdjLayer(NULL)
01730 {
01731 m_isSetting=true;
01732 lastElemAdjLayer=NULL;
01733 }
01734 FEM_Mesh::~FEM_Mesh() {
01735 }
01736
01737 FEM_Entity *FEM_Mesh::lookup(int entity,const char *caller) {
01738 FEM_Entity *e=NULL;
01739 if (entity>=FEM_ENTITY_FIRST && entity<FEM_ENTITY_LAST)
01740 {
01741 bool isGhost=false;
01742 if (entity-FEM_ENTITY_FIRST>=FEM_GHOST) {
01743 entity-=FEM_GHOST;
01744 isGhost=true;
01745 }
01746 if (entity==FEM_NODE)
01747 e=&node;
01748 else if (entity>=FEM_ELEM && entity<FEM_ELEM+100)
01749 {
01750 int elType=entity-FEM_ELEM;
01751 e=&elem.set(elType);
01752 }
01753 else if (entity>=FEM_SPARSE && entity<FEM_SPARSE+100)
01754 {
01755 int sID=entity-FEM_SPARSE;
01756 e=&sparse.set(sID);
01757 }
01758
01759 if (isGhost)
01760 e=e->getGhost();
01761 }
01762
01763 if (e==NULL)
01764 FEM_Abort(caller,"Expected an entity type (FEM_NODE, FEM_ELEM, etc.) but got %d",entity);
01765 return e;
01766 }
01767 const FEM_Entity *FEM_Mesh::lookup(int entity,const char *caller) const {
01770 return ((FEM_Mesh *)this)->lookup(entity,caller);
01771 }
01772
01773 void FEM_Mesh::setFemMeshModify(femMeshModify *m){
01774 fmMM = m;
01775 }
01776
01777
01778 femMeshModify *FEM_Mesh::getfmMM(){
01779 return fmMM;
01780 }
01781
01782 void FEM_Mesh::pup(PUP::er &p)
01783 {
01784 p.comment(" ------------- Node Data ---------- ");
01785 node.pup(p);
01786
01787 p.comment(" ------------- Element Types ---------- ");
01788 elem.pup(p);
01789
01790 p.comment("-------------- Sparse Types ------------");
01791 sparse.pup(p);
01792
01793 p.comment("-------------- Symmetries ------------");
01794 symList.pup(p);
01795
01796 p|m_isSetting;
01797
01798 p.comment("-------------- Mesh data --------------");
01799 udata.pup(p);
01800
01801
01802
01803
01804 }
01805
01806 int FEM_Mesh::chkET(int elType) const {
01807 if ((elType<0)||(elType>=elem.size())) {
01808 CkError("FEM Error! Bad element type %d!\n",elType);
01809 CkAbort("FEM Error! Bad element type used!\n");
01810 }
01811 return elType;
01812 }
01813
01814 int FEM_Mesh::nElems(int t_max) const
01815 {
01816 #if CMK_ERROR_CHECKING
01817 if (t_max<0 || t_max>elem.size()) {
01818 CkPrintf("FEM> Invalid element type %d used!\n");
01819 CkAbort("FEM> Invalid element type");
01820 }
01821 #endif
01822 int ret=0;
01823 for (int t=0;t<t_max;t++){
01824 if (elem.has(t)){
01825 ret+=elem.get(t).size();
01826 }
01827 }
01828 return ret;
01829 }
01830
01831 int FEM_Mesh::getGlobalElem(int elType,int elNo) const
01832 {
01833 int base=nElems(elType);
01834 #if CMK_ERROR_CHECKING
01835 if (elNo<0 || elNo>=elem[elType].size()) {
01836 CkPrintf("FEM> Element number %d is invalid-- element type %d has only %d elements\n",
01837 elNo,elType,elem[elType].size());
01838 CkAbort("FEM> Invalid element number, probably passed via FEM_Set_Sparse_elem");
01839 }
01840 #endif
01841 return base+elNo;
01842 }
01843
01845 void FEM_Mesh::setAscendingGlobalno(void) {
01846 node.setAscendingGlobalno();
01847 for (int e=0;e<elem.size();e++)
01848 if (elem.has(e)) elem[e].setAscendingGlobalno();
01849 for (int s=0;s<sparse.size();s++)
01850 if (sparse.has(s)) sparse[s].setAscendingGlobalno();
01851 }
01852 void FEM_Mesh::setAbsoluteGlobalno(){
01853 node.setAscendingGlobalno();
01854 for (int e=0;e<elem.size();e++){
01855 if (elem.has(e)) elem[e].setAscendingGlobalno(nElems(e));
01856 }
01857 }
01858
01859 void FEM_Mesh::copyOldGlobalno(const FEM_Mesh &m) {
01860 node.copyOldGlobalno(m.node);
01861 for (int e=0;e<m.elem.size();e++)
01862 if (m.elem.has(e) && e<elem.size() && elem.has(e))
01863 elem[e].copyOldGlobalno(m.elem[e]);
01864 for (int s=0;s<m.sparse.size();s++)
01865 if (m.sparse.has(s) && s<sparse.size() && sparse.has(s))
01866 sparse[s].copyOldGlobalno(m.sparse[s]);
01867 }
01868
01869 void FEM_Index_Check(const char *caller,const char *entityType,int type,int maxType) {
01870 if (type<0 || type>maxType) {
01871 char msg[1024];
01872 sprintf(msg,"%s %d is not a valid entity type (it must be between %d and %d)",
01873 entityType,type, 0, maxType-1);
01874 FEM_Abort(caller,msg);
01875 }
01876 }
01877 void FEM_Is_NULL(const char *caller,const char *entityType,int type) {
01878 char msg[1024];
01879 sprintf(msg,"%s %d was never set--it cannot now be read",entityType,type);
01880 FEM_Abort(caller,msg);
01881 }
01882
01883 void FEM_Mesh::copyShape(const FEM_Mesh &src)
01884 {
01885 node.copyShape(src.node);
01886 for (int t=0;t<src.elem.size();t++)
01887 if (src.elem.has(t)) elem.set(t).copyShape(src.elem.get(t));
01888
01889 for (int s=0;s<src.sparse.size();s++)
01890 if (src.sparse.has(s)) sparse.set(s).copyShape(src.sparse.get(s));
01891
01892 setSymList(src.getSymList());
01893 }
01894
01896 int FEM_Mesh::getEntities(int *entities) {
01897 int len=0;
01898 entities[len++]=FEM_NODE;
01899 for (int t=0;t<elem.size();t++)
01900 if (elem.has(t)) entities[len++]=FEM_ELEM+t;
01901 for (int s=0;s<sparse.size();s++)
01902 if (sparse.has(s)) entities[len++]=FEM_SPARSE+s;
01903 return len;
01904 }
01905
01906
01907 FILE *FEM_openMeshFile(const char *prefix,int chunkNo,int nchunks,bool forRead)
01908 {
01909 char fname[256];
01910 static const char *meshFileNames="%s_vp%d_%d.dat";
01911 sprintf(fname, meshFileNames, prefix, nchunks, chunkNo);
01912 FILE *fp = fopen(fname, forRead?"r":"w");
01913 CkPrintf("FEM> %s %s...\n",forRead?"Reading":"Writing",fname);
01914 if(fp==0) {
01915 FEM_Abort(forRead?"FEM: unable to open input file"
01916 :"FEM: unable to create output file.\n");
01917 }
01918 return fp;
01919 }
01920
01921 static inline void read_version()
01922 {
01923 FILE *f = fopen("FEMVERSION", "r");
01924 if (f!=NULL) {
01925 fscanf(f, "%d", &femVersion);
01926 if (CkMyPe()==0) CkPrintf("FEM> femVersion detected: %d\n", femVersion);
01927 fclose(f);
01928 }
01929 }
01930
01931 static inline void write_version()
01932 {
01933 FILE *f = fopen("FEMVERSION", "w");
01934 if (f!=NULL) {
01935 fprintf(f, "%d", femVersion);
01936 fclose(f);
01937 }
01938 }
01939
01940 FEM_Mesh *FEM_readMesh(const char *prefix,int chunkNo,int nChunks)
01941 {
01942
01943 static int version_checked = 0;
01944 if (!version_checked) {
01945 version_checked=1;
01946 read_version();
01947 }
01948
01949 FEM_Mesh *ret=new FEM_Mesh;
01950 ret->becomeGetting();
01951 FILE *fp = FEM_openMeshFile(prefix,chunkNo,nChunks,true);
01952 PUP::fromTextFile p(fp);
01953 ret->pup(p);
01954 fclose(fp);
01955
01956 #ifdef PRINT_SHARED_NODE_INFO
01957 FEM_Comm &shared = ret->node.shared;
01958 int numNeighborVPs = shared.size();
01959 CkPrintf("COMM DATA %d %d ", chunkNo, numNeighborVPs);
01960
01961 for(int i=0;i<numNeighborVPs;i++) {
01962 IDXL_List list = shared.getLocalList(i);
01963 CkPrintf("%d %d ", list.getDest(), list.size());
01964 }
01965 CkPrintf("\n");
01966 #endif
01967
01968 return ret;
01969 }
01970
01971 void FEM_writeMesh(FEM_Mesh *m,const char *prefix,int chunkNo,int nChunks)
01972 {
01973 if (chunkNo == 0) {
01974 write_version();
01975 }
01976 FILE *fp = FEM_openMeshFile(prefix,chunkNo,nChunks,false);
01977 PUP::toTextFile p(fp);
01978 m->pup(p);
01979 fclose(fp);
01980 }
01981
01982
01983
01984 CLINKAGE void FEM_Mesh_allocate_valid_attr(int fem_mesh, int entity_type){
01985 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_create_valid_elem");
01986 FEM_Entity *entity = m->lookup(entity_type,"FEM_Mesh_allocate_valid_attr");
01987 entity->allocateValid();
01988 }
01989 FORTRAN_AS_C(FEM_MESH_ALLOCATE_VALID_ATTR,
01990 FEM_Mesh_allocate_valid_attr,
01991 fem_mesh_allocate_valid_attr,
01992 (int *fem_mesh, int *entity_type), (*fem_mesh, *entity_type) )
01993
01994
01995
01996 CLINKAGE void FEM_set_entity_valid(int mesh, int entityType, int entityIdx){
01997 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_");
01998 FEM_Entity *entity = m->lookup(entityType,"FEM_");
01999 entity->set_valid(entityIdx,true);
02000 }
02001 FORTRAN_AS_C(FEM_SET_ENTITY_VALID,
02002 FEM_set_entity_valid,
02003 fem_set_entity_valid,
02004 (int *fem_mesh, int *entity_type, int *entityIdx), (*fem_mesh, *entity_type, *entityIdx) )
02005
02006
02007
02008 CLINKAGE void FEM_set_entity_invalid(int mesh, int entityType, int entityIdx){
02009 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Mesh_create_valid_elem");
02010 FEM_Entity *entity = m->lookup(entityType,"FEM_Mesh_allocate_valid_attr");
02011 return entity->set_invalid(entityIdx,true);
02012 }
02013 FORTRAN_AS_C(FEM_SET_ENTITY_INVALID,
02014 FEM_set_entity_invalid,
02015 fem_set_entity_invalid,
02016 (int *fem_mesh, int *entity_type, int *entityIdx), (*fem_mesh, *entity_type, *entityIdx) )
02017
02018
02019
02020 CLINKAGE int FEM_is_valid(int mesh, int entityType, int entityIdx){
02021 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Mesh_create_valid_elem");
02022 FEM_Entity *entity = m->lookup(entityType,"FEM_Mesh_allocate_valid_attr");
02023 return (entity->is_valid(entityIdx) != 0);
02024 }
02025 FORTRAN_AS_C(FEM_IS_VALID,
02026 FEM_is_valid,
02027 fem_is_valid,
02028 (int *fem_mesh, int *entity_type, int *entityIdx), (*fem_mesh, *entity_type, *entityIdx) )
02029
02030
02031
02032 CLINKAGE unsigned int FEM_count_valid(int mesh, int entityType){
02033 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Mesh_create_valid_elem");
02034 FEM_Entity *entity = m->lookup(entityType,"FEM_Mesh_allocate_valid_attr");
02035 return entity->count_valid();
02036 }
02037 FORTRAN_AS_C(FEM_COUNT_VALID,
02038 FEM_count_valid,
02039 fem_count_valid,
02040 (int *fem_mesh, int *entity_type), (*fem_mesh, *entity_type) )
02041
02042
02043
02044 void FEM_set_entity_coord2(int mesh, int entityType, int idx, double x, double y){
02045 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Mesh_create_valid_elem");
02046 FEM_Entity *entity = m->lookup(entityType,"FEM_Mesh_allocate_valid_attr");
02047 entity->set_coord(idx,x,y);
02048 }
02049 void FEM_set_entity_coord3(int mesh, int entityType, int idx, double x, double y, double z){
02050 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Mesh_create_valid_elem");
02051 FEM_Entity *entity = m->lookup(entityType,"FEM_Mesh_allocate_valid_attr");
02052 entity->set_coord(idx,x,y,z);
02053 }