00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ParFUM.h"
00010 #include "ParFUM_internals.h"
00011
00012 extern int femVersion;
00013
00014
00015 FEM_Comm_Holder::FEM_Comm_Holder(FEM_Comm *sendComm, FEM_Comm *recvComm)
00016 :comm(sendComm,recvComm)
00017 {
00018 registered=false;
00019 idx=-1;
00020 }
00021 void FEM_Comm_Holder::registerIdx(IDXL_Chunk *c) {
00022 assert(!registered);
00023 IDXL_Chunk *owner=c;
00024 if (idx!=-1)
00025 idx=owner->addStatic(&comm,idx);
00026 else
00027 idx=owner->addStatic(&comm);
00028 }
00029 void FEM_Comm_Holder::pup(PUP::er &p) {
00030 p|idx;
00031 if (p.isUnpacking() && idx!=-1)
00032 {
00033 registerIdx(IDXL_Chunk::get("FEM_Comm_Holder::pup"));
00034 }
00035 }
00036
00037 FEM_Comm_Holder::~FEM_Comm_Holder(void)
00038 {
00039 if (registered)
00040 {
00041 const char *caller="FEM_Comm_Holder::~FEM_Comm_Holder";
00042 IDXL_Chunk *owner=IDXL_Chunk::getNULL();
00043 if (owner) owner->destroy(idx,caller);
00044 }
00045 }
00046
00047
00048
00049 static void checkIsSet(int fem_mesh,bool wantSet,const char *caller) {
00050 if (FEM_Mesh_is_set(fem_mesh)!=wantSet) {
00051 const char *msg=wantSet?"This mesh (%d) is not a setting mesh":
00052 "This mesh (%d) is not a getting mesh";
00053 FEM_Abort(caller,msg,fem_mesh);
00054 }
00055 }
00056
00057
00058 CDECL void
00059 FEM_Mesh_conn(int fem_mesh,int entity,
00060 int *conn, int firstItem, int length, int width)
00061 {
00062 FEM_Mesh_data(fem_mesh,entity,FEM_CONN, conn, firstItem,length, FEM_INDEX_0, width);
00063 }
00064 FDECL void
00065 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(int *fem_mesh,int *entity,
00066 int *conn, int *firstItem,int *length, int *width)
00067 {
00068
00069 FEM_Mesh_data(*fem_mesh,*entity,FEM_CONN, conn, *firstItem-1,*length, FEM_INDEX_1, *width);
00070 }
00071
00072 CDECL void
00073 FEM_Mesh_set_conn(int fem_mesh,int entity,
00074 const int *conn, int firstItem,int length, int width)
00075 {
00076 checkIsSet(fem_mesh,true,"FEM_Mesh_set_conn");
00077 FEM_Mesh_conn(fem_mesh,entity,(int *)conn,firstItem,length,width);
00078 }
00079 FDECL void
00080 FTN_NAME(FEM_MESH_SET_CONN,fem_mesh_set_conn)(int *fem_mesh,int *entity,
00081 const int *conn, int *firstItem,int *length, int *width)
00082 {
00083 checkIsSet(*fem_mesh,true,"fem_mesh_set_conn");
00084 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(fem_mesh,entity,(int *)conn,firstItem,length,width);
00085 }
00086
00087 CDECL void
00088 FEM_Mesh_get_conn(int fem_mesh,int entity,
00089 int *conn, int firstItem,int length, int width)
00090 {
00091 checkIsSet(fem_mesh,false,"FEM_Mesh_get_conn");
00092 FEM_Mesh_conn(fem_mesh,entity,conn,firstItem,length,width);
00093 }
00094 FDECL void
00095 FTN_NAME(FEM_MESH_GET_CONN,fem_mesh_get_conn)(int *fem_mesh,int *entity,
00096 int *conn, int *firstItem,int *length, int *width)
00097 {
00098 checkIsSet(*fem_mesh,false,"fem_mesh_get_conn");
00099 FTN_NAME(FEM_MESH_CONN,fem_mesh_conn)(fem_mesh,entity,conn,firstItem,length,width);
00100 }
00101
00102
00103
00104 CDECL void
00105 FEM_Mesh_data(int fem_mesh,int entity,int attr,
00106 void *data, int firstItem,int length, int datatype,int width)
00107 {
00108 IDXL_Layout lo(datatype,width);
00109 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,lo);
00110 }
00111
00112 FORTRAN_AS_C(FEM_MESH_DATA,FEM_Mesh_data,fem_mesh_data,
00113 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00114 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00115 )
00116
00117
00118 CDECL void
00119 FEM_Mesh_set_data(int fem_mesh,int entity,int attr,
00120 const void *data, int firstItem,int length, int datatype,int width)
00121 {
00122 checkIsSet(fem_mesh,true,"FEM_Mesh_set_data");
00123 FEM_Mesh_data(fem_mesh,entity,attr,(void *)data,firstItem,length,datatype,width);
00124 }
00125 FORTRAN_AS_C(FEM_MESH_SET_DATA,FEM_Mesh_set_data,fem_mesh_set_data,
00126 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00127 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00128 )
00129
00130 CDECL void
00131 FEM_Mesh_get_data(int fem_mesh,int entity,int attr,
00132 void *data, int firstItem,int length, int datatype,int width)
00133 {
00134 checkIsSet(fem_mesh,false,"FEM_Mesh_get_data");
00135 FEM_Mesh_data(fem_mesh,entity,attr,data,firstItem,length,datatype,width);
00136 }
00137 FORTRAN_AS_C(FEM_MESH_GET_DATA,FEM_Mesh_get_data,fem_mesh_get_data,
00138 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *datatype,int *width),
00139 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*datatype,*width)
00140 )
00141
00142 CDECL void
00143 FEM_Mesh_data_layout(int fem_mesh,int entity,int attr,
00144 void *data, int firstItem,int length, IDXL_Layout_t layout)
00145 {
00146 const char *caller="FEM_Mesh_data_layout";
00147 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,
00148 IDXL_Layout_List::get().get(layout,caller));
00149 }
00150
00151 FORTRAN_AS_C(FEM_MESH_DATA_LAYOUT,FEM_Mesh_data_layout,fem_mesh_data_layout,
00152 (int *fem_mesh,int *entity,int *attr,void *data,int *firstItem,int *length,int *layout),
00153 (*fem_mesh,*entity,*attr,data,*firstItem-1,*length,*layout)
00154 )
00155
00156 CDECL void
00157 FEM_Mesh_data_offset(int fem_mesh,int entity,int attr,
00158 void *data, int firstItem,int length,
00159 int type,int width, int offsetBytes,int distanceBytes,int skewBytes)
00160 {
00161 const char *caller="FEM_Mesh_data_offset";
00162 FEM_Mesh_data_layout(fem_mesh,entity,attr,data,firstItem,length,
00163 IDXL_Layout(type,width,offsetBytes,distanceBytes,skewBytes));
00164 }
00165 FORTRAN_AS_C(FEM_MESH_DATA_OFFSET,FEM_Mesh_data_offset,fem_mesh_data_offset,
00166 (int *fem_mesh,int *entity,int *attr,
00167 void *data,int *firstItem,int *length,
00168 int *type,int *width,int *offset,int *distance,int *skew),
00169 (*fem_mesh,*entity,*attr,
00170 data,*firstItem-1,*length,
00171 *type,*width,*offset,*distance,*skew)
00172 )
00173
00174
00175 void FEM_Register_array(int fem_mesh,int entity,int attr,
00176 void *data, int datatype,int width,int firstItem){
00177 IDXL_Layout lo(datatype,width);
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 FEM_Register_array_layout(fem_mesh,entity,attr,data,firstItem,lo);
00188 }
00189
00190 void FEM_Register_array_layout(int fem_mesh,int entity,int attr,
00191 void *data, IDXL_Layout_t layout,int firstItem){
00192 const char *caller="FEM_Register_array_layout";
00193 FEM_Register_array_layout(fem_mesh,entity,attr,data,firstItem,
00194 IDXL_Layout_List::get().get(layout,caller));
00195
00196 }
00197
00198
00199 CDECL void
00200 FEM_Register_array(int fem_mesh,int entity,int attr,
00201 void *data, int datatype,int width)
00202 {
00203 FEM_Register_array(fem_mesh,entity,attr,data,datatype,width,0);
00204 }
00205
00206 CDECL void
00207 FEM_Register_array_layout(int fem_mesh,int entity,int attr,
00208 void *data, IDXL_Layout_t layout){
00209 FEM_Register_array_layout(fem_mesh,entity,attr,data,layout,0);
00210 }
00211
00212
00213 CDECL void
00214 FEM_Register_entity(int fem_mesh,int entity,void *data,
00215 int len,int max,FEM_Mesh_alloc_fn fn) {
00216 FEM_Register_entity_impl(fem_mesh,entity,data,len,max,fn);
00217 }
00218
00221 FORTRAN_AS_C(FEM_REGISTER_ARRAY,FEM_Register_array,fem_register_array,
00222 (int *fem_mesh,int *entity,int *attr,void *data,int *datatype,int *width),(*fem_mesh,*entity,*attr,data,*datatype,*width,0))
00223
00224
00225 FORTRAN_AS_C(FEM_REGISTER_ARRAY_LAYOUT,FEM_Register_array_layout,fem_register_array_layout,
00226 (int *fem_mesh,int *entity,int *attr,void *data,int *layout),(*fem_mesh,*entity,*attr,data,*layout,0))
00227
00228 FORTRAN_AS_C(FEM_REGISTER_ENTITY,FEM_Register_entity,fem_register_entity,
00229 (int *fem_mesh,int *entity,void *data,int *len,int *max,FEM_Mesh_alloc_fn fn),(*fem_mesh,*entity,data,*len,*max,fn))
00230
00231
00232
00233 CDECL void
00234 FEM_Mesh_pup(int fem_mesh,int dataTag,FEM_Userdata_fn fn,void *data) {
00235 const char *caller="FEM_Mesh_pup"; FEMAPI(caller);
00236 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00237 FEM_Userdata_item &i=m->udata.find(dataTag);
00238 FEM_Userdata_pupfn f(fn,data);
00239 if (m->isSetting()) i.store(f);
00240 else {
00241 if (!i.hasStored())
00242 FEM_Abort(caller,"Never stored any user data at tag %d",dataTag);
00243 i.restore(f);
00244 }
00245 }
00246 FORTRAN_AS_C(FEM_MESH_PUP,FEM_Mesh_pup,fem_mesh_pup,
00247 (int *m,int *t,FEM_Userdata_fn fn,void *data), (*m,*t,fn,data))
00248
00249
00250 CDECL void
00251 FEM_Mesh_set_length(int fem_mesh,int entity,int newLength) {
00252 const char *caller="FEM_Mesh_set_length"; FEMAPI(caller);
00253 checkIsSet(fem_mesh,true,caller);
00254 FEM_Entity_lookup(fem_mesh,entity,caller)->setLength(newLength);
00255 }
00256 FORTRAN_AS_C(FEM_MESH_SET_LENGTH,FEM_Mesh_set_length,fem_mesh_set_length,
00257 (int *fem_mesh,int *entity,int *newLength),
00258 (*fem_mesh,*entity,*newLength)
00259 )
00260
00261
00262 CDECL int
00263 FEM_Mesh_get_length(int fem_mesh,int entity) {
00264 const char *caller="FEM_Mesh_get_length"; FEMAPI(caller);
00265 int len=FEM_Entity_lookup(fem_mesh,entity,caller)->size();
00266 return len;
00267 }
00268 FORTRAN_AS_C_RETURN(int,
00269 FEM_MESH_GET_LENGTH,FEM_Mesh_get_length,fem_mesh_get_length,
00270 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00271 )
00272
00273
00274 CDECL void
00275 FEM_Mesh_set_width(int fem_mesh,int entity,int attr,int newWidth) {
00276 const char *caller="FEM_Mesh_set_width";
00277 FEMAPI(caller);
00278 checkIsSet(fem_mesh,true,caller);
00279 FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->setWidth(newWidth,caller);
00280 }
00281 FORTRAN_AS_C(FEM_MESH_SET_WIDTH,FEM_Mesh_set_width,fem_mesh_set_width,
00282 (int *fem_mesh,int *entity,int *attr,int *newWidth),
00283 (*fem_mesh,*entity,*attr,*newWidth)
00284 )
00285
00286 CDECL int
00287 FEM_Mesh_get_width(int fem_mesh,int entity,int attr) {
00288 const char *caller="FEM_Mesh_get_width";
00289 FEMAPI(caller);
00290 return FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->getWidth();
00291 }
00292 FORTRAN_AS_C_RETURN(int,
00293 FEM_MESH_GET_WIDTH,FEM_Mesh_get_width,fem_mesh_get_width,
00294 (int *fem_mesh,int *entity,int *attr),(*fem_mesh,*entity,*attr)
00295 )
00296
00297 CDECL int
00298 FEM_Mesh_get_datatype(int fem_mesh,int entity,int attr) {
00299 const char *caller="FEM_Mesh_get_datatype";
00300 FEMAPI(caller);
00301 return FEM_Attribute_lookup(fem_mesh,entity,attr,caller)->getDatatype();
00302 }
00303 FORTRAN_AS_C_RETURN(int,
00304 FEM_MESH_GET_DATATYPE,FEM_Mesh_get_datatype,fem_mesh_get_datatype,
00305 (int *fem_mesh,int *entity,int *attr),(*fem_mesh,*entity,*attr)
00306 )
00307
00308 CDECL int
00309 FEM_Mesh_is_set(int fem_mesh)
00310 {
00311 return (FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_is_get")->isSetting())?1:0;
00312 }
00313 FORTRAN_AS_C_RETURN(int,
00314 FEM_MESH_IS_SET,FEM_Mesh_is_set,fem_mesh_is_set,
00315 (int *fem_mesh),(*fem_mesh)
00316 )
00317
00318 CDECL int
00319 FEM_Mesh_is_get(int fem_mesh)
00320 {
00321 return (!FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_is_get")->isSetting())?1:0;
00322 }
00323 FORTRAN_AS_C_RETURN(int,
00324 FEM_MESH_IS_GET,FEM_Mesh_is_get,fem_mesh_is_get,
00325 (int *fem_mesh),(*fem_mesh)
00326 )
00327
00328 CDECL void
00329 FEM_Mesh_become_get(int fem_mesh)
00330 { FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_become_get")->becomeGetting(); }
00331 FORTRAN_AS_C(FEM_MESH_BECOME_GET,FEM_Mesh_become_get,fem_mesh_become_get, (int *m),(*m))
00332
00333 CDECL void
00334 FEM_Mesh_become_set(int fem_mesh)
00335 { FEM_Mesh_lookup(fem_mesh,"FEM_Mesh_become_get")->becomeSetting(); }
00336 FORTRAN_AS_C(FEM_MESH_BECOME_SET,FEM_Mesh_become_set,fem_mesh_become_set, (int *m),(*m))
00337
00338
00339 CDECL IDXL_t
00340 FEM_Comm_shared(int fem_mesh,int entity) {
00341 const char *caller="FEM_Comm_shared";
00342 FEMAPI(caller);
00343 if (entity!=FEM_NODE) FEM_Abort(caller,"Only shared nodes supported");
00344 return FEM_Mesh_lookup(fem_mesh,caller)->node.
00345 sharedIDXL.getIndex(IDXL_Chunk::get(caller));
00346 }
00347 FORTRAN_AS_C_RETURN(int,
00348 FEM_COMM_SHARED,FEM_Comm_shared,fem_comm_shared,
00349 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00350 )
00351
00352 CDECL IDXL_t
00353 FEM_Comm_ghost(int fem_mesh,int entity) {
00354 const char *caller="FEM_Comm_ghost";
00355 FEMAPI(caller);
00356 FEM_Entity *e=FEM_Entity_lookup(fem_mesh,entity,caller);
00357 if (e->isGhost()) FEM_Abort(caller,"Can only call FEM_Comm_ghost on real entity type");
00358 return e->ghostIDXL.getIndex(IDXL_Chunk::get(caller));
00359 }
00360 FORTRAN_AS_C_RETURN(int,
00361 FEM_COMM_GHOST,FEM_Comm_ghost,fem_comm_ghost,
00362 (int *fem_mesh,int *entity),(*fem_mesh,*entity)
00363 )
00364
00365
00366
00367 void FEM_Mesh_data_layout(int fem_mesh,int entity,int attr,
00368 void *data, int firstItem,int length, const IDXL_Layout &layout)
00369 {
00370 if (femVersion == 0 && length==0) return;
00371 const char *caller="FEM_Mesh_data";
00372 FEMAPI(caller);
00373 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00374 FEM_Attribute *a=m->lookup(entity,caller)->lookup(attr,caller);
00375
00376 if (m->isSetting())
00377 a->set(data,firstItem,length,layout,caller);
00378 else
00379 a->get(data,firstItem,length,layout,caller);
00380 }
00381
00383 void FEM_Register_array_layout(int fem_mesh,int entity,int attr,void *data,int firstItem,const IDXL_Layout &layout){
00384 const char *caller="FEM_Register_array";
00385 FEMAPI(caller);
00386 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00387 FEM_Entity *e = m->lookup(entity,caller);
00388 int length = e->size();
00389
00390 int max = e->getMax();
00391 FEM_Attribute *a = e->lookup(attr,caller);
00392 if(a->getWidth() == 0){
00396
00397 a->setWidth(layout.width);
00398 }
00399
00400
00401 if(m->isSetting()){
00402 a->register_data(data,length,max,layout,caller);
00403 }else{
00404 a->get(data,firstItem,length,layout,caller);
00405
00406 a->register_data(data,max,max,layout,caller);
00407 }
00408 }
00409 void FEM_Register_entity_impl(int fem_mesh,int entity,void *args,int len,int max,FEM_Mesh_alloc_fn fn){
00410 char *caller = "FEM_Register_entity";
00411 FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller);
00412
00413
00414
00415
00416 FEM_Entity *e = m->lookup(entity,caller);
00417 e->setMaxLength(len,max,args,fn);
00418 }
00419
00420 FEM_Entity *FEM_Entity_lookup(int fem_mesh,int entity,const char *caller) {
00421 return FEM_Mesh_lookup(fem_mesh,caller)->lookup(entity,caller);
00422 }
00423 FEM_Attribute *FEM_Attribute_lookup(int fem_mesh,int entity,int attr,const char *caller) {
00424 return FEM_Entity_lookup(fem_mesh,entity,caller)->lookup(attr,caller);
00425 }
00426
00427 CDECL int FEM_Mesh_get_entities(int fem_mesh, int *entities) {
00428 const char *caller="FEM_Mesh_get_entities";
00429 FEMAPI(caller);
00430 return FEM_Mesh_lookup(fem_mesh,caller)->getEntities(entities);
00431 }
00432 FORTRAN_AS_C_RETURN(int,
00433 FEM_MESH_GET_ENTITIES,FEM_Mesh_get_entities,fem_mesh_get_entities,
00434 (int *mesh,int *ent), (*mesh,ent)
00435 )
00436
00437 CDECL int FEM_Mesh_get_attributes(int fem_mesh,int entity,int *attributes) {
00438 const char *caller="FEM_Mesh_get_attributes";
00439 FEMAPI(caller);
00440 return FEM_Entity_lookup(fem_mesh,entity,caller)->getAttrs(attributes);
00441 }
00442 FORTRAN_AS_C_RETURN(int,
00443 FEM_MESH_GET_ATTRIBUTES,FEM_Mesh_get_attributes,fem_mesh_get_attributes,
00444 (int *mesh,int *ent,int *attrs), (*mesh,*ent,attrs)
00445 )
00446
00447
00448
00449 CDECL const char *FEM_Get_datatype_name(int datatype,char *storage) {
00450 switch(datatype) {
00451 case FEM_BYTE: return "FEM_BYTE";
00452 case FEM_INT: return "FEM_INT";
00453 case FEM_FLOAT: return "FEM_FLOAT";
00454 case FEM_DOUBLE: return "FEM_DOUBLE";
00455 case FEM_INDEX_0: return "FEM_INDEX_0";
00456 case FEM_INDEX_1: return "FEM_INDEX_1";
00457 };
00458 sprintf(storage,"unknown datatype code (%d)",datatype);
00459 return storage;
00460 }
00461
00464 CDECL const char *FEM_Get_attr_name(int attr,char *storage)
00465 {
00466 if (attr<FEM_ATTRIB_TAG_MAX)
00467 {
00468 sprintf(storage,"FEM_DATA+%d",attr-FEM_DATA);
00469 return storage;
00470 }
00471 switch(attr) {
00472 case FEM_CONN: return "FEM_CONN";
00473 case FEM_SPARSE_ELEM: return "FEM_SPARSE_ELEM";
00474 case FEM_COOR: return "FEM_COOR";
00475 case FEM_GLOBALNO: return "FEM_GLOBALNO";
00476 case FEM_PARTITION: return "FEM_PARTITION";
00477 case FEM_SYMMETRIES: return "FEM_SYMMETRIES";
00478 case FEM_NODE_PRIMARY: return "FEM_NODE_PRIMARY";
00479 case FEM_NODE_ELEM_ADJACENCY: return "FEM_NODE_ELEM_ADJACENCY";
00480 case FEM_NODE_NODE_ADJACENCY: return "FEM_NODE_NODE_ADJACENCY";
00481 case FEM_ELEM_ELEM_ADJACENCY: return "FEM_ELEM_ELEM_ADJACENCY";
00482 case FEM_ELEM_ELEM_ADJ_TYPES: return "FEM_ELEM_ELEM_ADJ_TYPES";
00483 case FEM_IS_VALID_ATTR: return "FEM_IS_VALID_ATTR";
00484 case FEM_MESH_SIZING: return "FEM_MESH_SIZING";
00485
00486 default: break;
00487 };
00488 sprintf(storage,"unknown attribute code (%d)",attr);
00489 return storage;
00490 }
00491
00492
00493
00494 void FEM_Attribute::bad(const char *field,bool forRead,int cur,int next,const char *caller) const
00495 {
00496 char nameStorage[256];
00497 const char *name=FEM_Get_attr_name(attr,nameStorage);
00498 char errBuf[1024];
00499 const char *cannotBe=NULL;
00500 if (forRead) {
00501 if (cur==-1) {
00502 sprintf(errBuf,"The %s %s %s was never set-- it cannot now be read",
00503 e->getName(),name,field);
00504 }
00505 else
00506 cannotBe="read as";
00507 }
00508 else {
00509 cannotBe="set to";
00510 }
00511 if (cannotBe!=NULL)
00512 sprintf(errBuf,"The %s %s %s was previously set to %d; it cannot now be %s %d",
00513 e->getName(),name,field,cur,cannotBe,next);
00514
00515 FEM_Abort(caller,errBuf);
00516 }
00517
00518
00519 FEM_Attribute::FEM_Attribute(FEM_Entity *e_,int attr_)
00520 :e(e_),ghost(0),attr(attr_),width(0),datatype(-1), allocated(false)
00521 {
00522 tryAllocate();
00523 if (femVersion == 0) width=-1;
00524 }
00525 void FEM_Attribute::pup(PUP::er &p) {
00526
00527 p|width;
00528 if (p.isUnpacking() && femVersion > 0 && width<0) width=0;
00529 p|datatype;
00530 if (p.isUnpacking()) tryAllocate();
00531 }
00532 void FEM_Attribute::pupSingle(PUP::er &p, int pupindx) {
00533 return;
00534 }
00535 FEM_Attribute::~FEM_Attribute() {}
00536
00537 void FEM_Attribute::setLength(int next,const char *caller) {
00538 int cur=getLength();
00539 if (next==cur) return;
00540 if (cur>0) bad("length",false,cur,next, caller);
00541 e->setLength(next);
00542 tryAllocate();
00543 }
00544
00545 void FEM_Attribute::setWidth(int next,const char *caller) {
00546 int cur=getWidth();
00547 if (next==cur) return;
00548 if (cur>0) bad("width",false,cur,next, caller);
00549 width=next;
00550 tryAllocate();
00551 if (ghost) ghost->setWidth(width,caller);
00552 }
00553
00554 void FEM_Attribute::setDatatype(int next,const char *caller) {
00555 int cur=getDatatype();
00556 if (next==cur) return;
00557 if (cur!=-1) bad("datatype",false,cur,next, caller);
00558 datatype=next;
00559 tryAllocate();
00560 if (ghost) ghost->setDatatype(datatype,caller);
00561 }
00562
00563 void FEM_Attribute::copyShape(const FEM_Attribute &src) {
00564 setWidth(src.getWidth());
00565 if (src.getDatatype()!=-1)
00566 setDatatype(src.getDatatype());
00567 }
00568 void FEM_Attribute::set(const void *src, int firstItem,int length,
00569 const IDXL_Layout &layout, const char *caller)
00570 {
00571 if (firstItem!=0) {
00572 if (length!=1)
00573 CmiAbort("FEM_Mesh_data: unexpected firstItem");
00574 }
00575
00576 if (femVersion == 0 && getRealLength() == -1) setLength(length);
00577 else if (getLength()==0) setLength(length);
00578 else if (length!=1 && length!=getLength())
00579 bad("length",false,getLength(),length, caller);
00580
00581 int width=layout.width;
00582 if (femVersion==0 && getRealWidth()==-1) setWidth(width);
00583 else if (getWidth()==0) setWidth(width);
00584 else if (width!=getWidth())
00585 bad("width",false,getWidth(),width, caller);
00586
00587 int datatype=layout.type;
00588 if (getDatatype()==-1) setDatatype(datatype);
00589 else if (datatype!=getDatatype())
00590 bad("datatype",false,getDatatype(),datatype, caller);
00591
00592
00593
00594 }
00595
00596 void FEM_Attribute::get(void *dest, int firstItem,int length,
00597 const IDXL_Layout &layout, const char *caller) const
00598 {
00599 if (length==0) return;
00600 if (length!=1 && length!=getLength())
00601 bad("length",true,getLength(),length, caller);
00602
00603 int width=layout.width;
00604 if (width!=getWidth())
00605 bad("width",true,getWidth(),width, caller);
00606
00607 int datatype=layout.type;
00608 if (datatype!=getDatatype())
00609 bad("datatype",true,getDatatype(),datatype, caller);
00610
00611
00612 }
00613
00614
00615
00616 void FEM_Attribute::register_data(void *user, int length,int max,
00617 const IDXL_Layout &layout, const char *caller){
00618
00619 int width=layout.width;
00620 if (femVersion == 0 && getRealWidth()==-1) setWidth(width);
00621 else if (getWidth()==0){
00622 setWidth(width);
00623 }else{
00624 if (width!=getWidth()){
00625 bad("width",false,getWidth(),width, caller);
00626 }
00627 }
00628
00629 int datatype=layout.type;
00630 if (getDatatype()==-1){
00631 setDatatype(datatype);
00632 }else{
00633 if (datatype!=getDatatype()){
00634 bad("datatype",false,getDatatype(),datatype, caller);
00635 }
00636 }
00637
00638 }
00639
00640
00641
00642 void FEM_Attribute::tryAllocate(void) {
00643 int lenNull, widthNull;
00644 if (femVersion == 0) {
00645
00646 lenNull = (getRealLength()==-1);
00647 widthNull = (getRealWidth()==-1);
00648 }
00649 else {
00650 lenNull = (getLength()==0);
00651 widthNull = (getWidth()==0);
00652 }
00653 if ((!allocated) && !lenNull && !widthNull && getDatatype()!=-1) {
00654 allocated=true;
00655 allocate(getMax(),getWidth(),getDatatype());
00656 }
00657 }
00658
00659
00660 FEM_DataAttribute::FEM_DataAttribute(FEM_Entity *e,int myAttr)
00661 :FEM_Attribute(e,myAttr),
00662 char_data(0),int_data(0),float_data(0),double_data(0)
00663 {
00664 }
00665 void FEM_DataAttribute::pup(PUP::er &p) {
00666 super::pup(p);
00667 switch(getDatatype()) {
00668 case -1: break;
00669 case FEM_BYTE:
00670 if (char_data) {
00671
00672
00673
00674 char_data->pup(p);
00675 }
00676 break;
00677 case FEM_INT:
00678 if (int_data) {
00679
00680
00681
00682 int_data->pup(p);
00683 }
00684 break;
00685 case FEM_FLOAT:
00686 if (float_data) {
00687
00688
00689
00690 float_data->pup(p);
00691 }
00692 break;
00693 case FEM_DOUBLE:
00694 if (double_data) {
00695
00696
00697
00698 double_data->pup(p);
00699 }
00700 break;
00701 default: CkAbort("Invalid datatype in FEM_DataAttribute::pup");
00702 }
00703 }
00704 void FEM_DataAttribute::pupSingle(PUP::er &p, int pupindx) {
00705 super::pupSingle(p,pupindx);
00706 switch(getDatatype()) {
00707 case -1: break;
00708 case FEM_BYTE: if (char_data) char_data->pupSingle(p,pupindx); break;
00709 case FEM_INT: if (int_data) int_data->pupSingle(p,pupindx); break;
00710 case FEM_FLOAT: if (float_data) float_data->pupSingle(p,pupindx); break;
00711 case FEM_DOUBLE: if (double_data) double_data->pupSingle(p,pupindx); break;
00712 default: CkAbort("Invalid datatype in FEM_DataAttribute::pupSingle");
00713 }
00714 }
00715 FEM_DataAttribute::~FEM_DataAttribute() {
00716 if (char_data) delete char_data;
00717 if (int_data) delete int_data;
00718 if (float_data) delete float_data;
00719 if (double_data) delete double_data;
00720
00721 }
00722
00724 template <class T>
00725 inline void setTableData(const void *user, int firstItem, int length,
00726 IDXL_LAYOUT_PARAM, AllocTable2d<T> *table)
00727 {
00728 for (int r=0;r<length;r++) {
00729 register T *tableRow=table->getRow(firstItem+r);
00730 for (int c=0;c<width;c++)
00731 tableRow[c]=IDXL_LAYOUT_DEREF(T,user,r,c);
00732 }
00733 }
00734
00736 template <class T>
00737 inline void getTableData(void *user, int firstItem, int length,
00738 IDXL_LAYOUT_PARAM, const AllocTable2d<T> *table)
00739 {
00740 for (int r=0;r<length;r++) {
00741 register const T *tableRow=table->getRow(firstItem+r);
00742 for (int c=0;c<width;c++)
00743 IDXL_LAYOUT_DEREF(T,user,r,c)=tableRow[c];
00744 }
00745
00746 }
00747
00748 void FEM_DataAttribute::set(const void *u, int f,int l,