00001
00002
00003
00004
00005
00006
#ifndef __ATHENA_H__
00007
#define __ATHENA_H__
00008
00009
#if defined(PROM_USE_IBM_LARGE_FILES)
00010
#define _LARGE_FILES // IBM
00011
#endif
00012
00013
#include "prom_elem.hh"
00014
#include "prom_options.hh"
00015
#include "prom_perf.hh"
00016
00017
00018
#if defined(PARCH_win32)
00019
namespace {
00020
const signed char CASE_OFFSET =
'a' -
'A';
00021 }
00022
int strncasecmp(
const char s1[],
const char s2[],
int n)
00023 {
00024
for (
int p = 0; p < n; ++p) {
00025
char c1 = s1[p];
00026
char c2 = s2[p];
00027
if (c1 >=
'A' && c1 <=
'Z')
00028 c1 += CASE_OFFSET;
00029
if (c2 >=
'A' && c2 <=
'Z')
00030 c2 += CASE_OFFSET;
00031
if (c1 < c2)
00032
return -1;
00033
else if (c1 > c2)
00034
return 1;
00035
else if (c1 == 0 && c2 == 0)
00036
return 0;
00037 }
00038
return 0;
00039 }
00040
#endif
00041
00043
00044
00045
class AthenaFile
00046 {
00047
public:
00048 AthenaFile( MPI_Comm comm,
char *name,
char *type,
const int tag,
00049
const int factor = 1, AthenaFile *ifile = NULL );
00050 AthenaFile(
char *name,
char *type );
00051 ~AthenaFile();
00052
char *afgets(
char *buff2,
int bsz );
00053
int afprintf(
const char *string );
00054
int afprintf(
char *string,
char* );
00055
int afprintf(
char *string,
int );
00056
int afprintf(
char *string,
int,
int );
00057
int afprintf(
char *string,
int,
double );
00058
int afprintf(
char *string,
double);
00059
int afprintf(
char *string,
int,
double,
double,
double);
00060
int afprintf(
char *string,
int,
int,
double,
double,
double);
00061
int afprintf(
char *string,
int,
int,
int );
00062
int afprintf(
char *string,
int,
int,
int,
int );
00063
int afprintf(
char *string,
int,
int,
int,
int,
int,
int);
00064
int AdvanceFile(
int &num,
const int nIreal,
const int coord_lsz );
00065
bool isForFEAP()
const {
return file_!=NULL; }
00066
00067 FILE *file_;
00068
char *ptr_;
00069
char *base_;
00070
long int cnt_;
00071 };
00072
00074
00075
00076
class AthenaNode :
public PromStack,
public PromMaterial
00077 {
00078
public:
00079 AthenaNode(
int fid=-9,
int gid=-9,
int p=-9) {
00080 setFeap(fid); index_.setGlobal(gid); ghost_.setProc( p ); }
00081
00082 AthenaNode &operator=(
const AthenaNode &a ){
00083 assert(
this!=NULL);
00084 ghost_ = a.ghost_;
00085 index_ = a.index_;
00086 coord_ = a.coord_;
00087 fIndex_ = a.fIndex_;
00088
return *
this;
00089 }
00090
00091
int feap(
int &ierr )
const{ierr = !(
this && fIndex_ >= 0);
return fIndex_;}
00092
int feap()const{ assert(
this!=NULL && fIndex_ >= 0);
return fIndex_;}
00093
void setFeap(
int f ){ assert(
this!=NULL); fIndex_ = f; }
00094
virtual int WriteFeap( AthenaFile *file )
const ;
00095
int Read(
int **buff );
00096
int Write(
int **buff )
const;
00097
static int GetWrite_size(
int &sz );
00098
bool isGhost()const{
int ierr;
return (ghost_.proc(ierr) >= 0); }
00099
00100
public:
00101
int fIndex_;
00102
PromGlobalID ghost_;
00103
PromLocalID index_;
00104
PromCoord coord_;
00105 };
00106
00108
00109
00110
class AthenaElem :
public PromStack,
public PromMaterial
00111 {
00112
protected:
00113 AthenaElem() : isghost_(FALSE), fid_(0), nNodes_(0), nodes_(NULL) {
00114 angles_[0] = angles_[1] = angles_[2] = angles_[3] = -9.0;
00115 }
00116
int Init1(
int feapid,
int mat,
int nen,
int *nds,
int *buff );
00117
int Read(
int nns,
int *nds,
int *&buff );
00118
public:
00119
00120
int Write(
int *&buff );
00121
virtual int isErr()=0;
00122
int GetWrite_size(
int &sz )
const;
00123
int WriteFeap(AthenaFile *file,
const PromTable<int> &fid1_lid1,
00124
const PromTable<AthenaNode*> &fid1_ghost,
00125
const int lid1,
const int nen_max,
bool write_ang)
const;
00126
int numNodes()const{
return nNodes_; }
00127
int getFID()const{ assert(
this!=NULL && fid_ != -9);
return fid_; }
00128
int getFID(
int &ierr)
const{
00129 assert(
this!=NULL);ierr=(fid_==-9);
return fid_;
00130 }
00131
void setFID(
int id ){assert(
this!=NULL); fid_ =
id;}
00132
bool isGhost()const{
return isghost_; }
00133
void setGhost(
bool b = TRUE ){ isghost_ = b; }
00134
00135
protected:
00136
bool isghost_;
00137
int fid_;
00138
int nNodes_;
00139
public:
00140
int *nodes_;
00141
float angles_[4];
00142 };
00143
00145
00146
00147
class AthenaElem8 :
public AthenaElem
00148 {
00149
public:
00150 AthenaElem8(
int *&buff ){
00151
int ierr = Read( 8, nodes_private_, buff );
00152 }
00153 AthenaElem8(
int fpid,
int mat,
int *buff ) {
00154
int ierr = Init1( fpid, mat, 8, nodes_private_, buff );
00155 }
00156
virtual int isErr(){
00157 assert(
this!=NULL);
00158
return (nodes_private_ != nodes_ || nNodes_ != 8);
00159 }
00160
private:
00161
int nodes_private_[8];
00162 };
00163
00165
00166
00167
class AthenaElem4 :
public AthenaElem
00168 {
00169
public:
00170 AthenaElem4(
int *&buff ){
00171
int ierr = Read( 4, nodes_private_, buff );
00172 }
00173 AthenaElem4(
int fpid,
int mat,
int *buff ) {
00174 Init1( fpid, mat, 4, nodes_private_, buff );
00175 }
00176
virtual int isErr(){
00177 assert(
this!=NULL);
00178
return (nodes_private_ != nodes_ || nNodes_ != 4);
00179 }
00180
private:
00181
int nodes_private_[4];
00182 };
00183
00185
00186
00187
class AthenaElemX :
public AthenaElem
00188 {
00189
public:
00190 AthenaElemX(
int *&buff ) {
00191 nen_ = *buff; assert( nen_ > 0 );
00192 PetscMalloc(nen_*
sizeof(
int),&nodes_private_);
00193 Read( nen_, nodes_private_, buff );
00194 }
00195 AthenaElemX(
int nen,
int fpid,
int mat,
int *buff ) : nen_(nen) {
00196 assert( nen > 0 );
00197 PetscMalloc( nen*
sizeof(
int), &nodes_private_ );
00198 Init1( fpid, mat, nen, nodes_private_, buff );
00199 }
00200 ~AthenaElemX(){ PetscFree(nodes_private_); }
00201
virtual int isErr(){
00202 assert(
this!=NULL);
00203
return (nodes_private_ != nodes_);
00204 }
00205
private:
00206
int nen_;
00207
int *nodes_private_;
00208 };
00209
00211
00214 class PromCommSpecs
00215 {
00216
public:
00217
PromCommSpecs(
double mfl = 100.0,
double bd = 1.e+7,
double lat = 1.e-5) {
00218 latency_ = lat; bandwidth_ = bd; mflops_ = mfl;}
00219
int GetWeights(
const int ndf,
int &edgew,
int &nodew,
int &edgeconst );
00220
void print()
const {
00221 PetscPrintf( MPI_COMM_WORLD,
00222
"PromCommSpecs<mflops=%e,band width=%e,latentcy=%e>\n",
00223 mflops_, bandwidth_, latency_);
00224 }
00225
private:
00226
double latency_, bandwidth_, mflops_;
00227 };
00228
00230
00231
00232
class AthenaPartition :
public PromContext
00233 {
00234
friend class Athena;
00235
public:
00236 AthenaPartition(
const int myprocess,
const int nprocess,
const int nparts,
00237
const int sp,
const int ep,
const int inpgn,
00238
const int inpge,
const PromComm &comm,
00239 PromOptions &opts, PromPerfMonitor &perf);
00240 AthenaPartition(
const AthenaPartition *part1,
00241
const PromComm &comm, PromOptions &opts, PromPerfMonitor &perf );
00242
virtual ~AthenaPartition();
00243
00244
00245
int Distribute( AthenaFile*, AthenaFile*,
PromCommSpecs &commsp,
int &nElems,
00246
const bool last );
00247
protected:
00248
virtual int ReadIfile( AthenaFile* Ifile,
int &nTotalNd,
int &nElems,
00249 PromList<AthenaElem*> &elems,
00250 AthenaNode **&inputGhosts ) = 0;
00251
virtual int Write(AthenaFile *Ifile, AthenaFile *Ofile,
const int nIghost,
00252
const PromTable<int> &fnodes,
00253
const PromTable<AthenaNode*> &ghosts,
00254 PromList<AthenaElem*> &elems) = 0;
00255
int Init(
const int startp,
const int stepp);
00256
int MakeDummy(
const AthenaPartition *part1 );
00257
int Reorder(
const PromList<AthenaElem*> &elems,
00258
const PromTable<int> &fid1_lid1,
00259
const PromTable<AthenaNode*> &fid1_ghost );
00260
int Partition(
PromCommSpecs &commsp,
const int nIreal,
00261
const PromList<AthenaElem*> &elems,
int *&out );
00262
int CollectData(
const int maxloc,
const int fnode_part[],
00263 PromList<AthenaElem*> &elems,
00264 PromTable<int> &fnodes,
00265 PromTable<AthenaNode*> &fghost,
00266
const bool last );
00267
int CollectNewNodes(
const int maxloc,
const int fnode_part[],
00268 PromTable<int> &fnodes );
00269
int CollectNodeData(
const int fnode_part[],
00270
const PromTable<int> &fnodes,
int forig_gnode[] );
00271
int Send_RecvElemData(
const AthenaNode orn[],
const int forig_gnode[],
00272 PromList<AthenaElem*> &elems,
00273
const PromTable<int> &fnodes,
00274 PromTable<AthenaNode*> &fid1_ghost,
00275
const int fnode_part[] );
00276
int ReadAElem(
int *buf,
int &sz,
const PromTable<int> &fid1_lid1,
00277 PromTable<AthenaNode*> &fid1_ghost,
00278 PromTable<AthenaElem*> &felid1_elem,
00279 PromList<AthenaElem*> &elems,
00280 PromTable<PromList<int*>*> &proc_list );
00281
int GetGhostTable(
const PromTable<int> &fid1_lid1,
00282 PromTable<AthenaNode*> &fid1_ghost,
00283 AthenaNode **inputGhosts,
00284 PromList<AthenaElem*> &elems);
00285
int CollectElemData(
const int nIelems,PromList<AthenaElem*> &elems);
00286
int PickRealElems(
const PromTable<int> &fid1_lid1,
00287
const PromTable<AthenaNode*> &fid1_ghost,
00288
const int nI, PromList<AthenaElem*> &relems,
00289 PromList<AthenaElem*> &elems );
00290
int CalcOrder(
const PromList<AthenaElem*> &elems,
00291
const PromTable<int> &fid1_,
int *old_new);
00292
int LocalReorder(
const PromTable<int> &fid1_lid1,
00293
const PromTable<AthenaNode*> &fid1_ghost,
00294
const PromList<AthenaElem*> &elems,
00295
const int old_new[] );
00296
int BfsOrder(PromTable<AthenaNode*> &list1,
00297
const PromTable<AthenaNode*> adjacs[],
int old_new[] );
00298
int AthenaPartitionOrder(
const int nblocs,
00299 PromTable<AthenaNode*> &list1,
00300
const PromTable<AthenaNode*> adjacs[],
00301
int old_new[],
const int blockIS_flag );
00302
int AddRing(
const PromTable<AthenaNode*> &list4,
00303 PromList<AthenaNode*> &list3,
00304
const PromTable<AthenaNode*> adjacs[],
00305 AthenaNode *&curr,
int &ndone,
int old_new[] );
00306
00307
const int nCommprocs_;
00308
const int myCommproc_;
00309
const int nparts_;
00310 MPI_Comm MPIComm_;
00311 MPI_Group Group_;
00312 MPI_Group mpi_group_world_;
00313
public:
00314
const int nIghostNodes_;
00315
const int nIghostElems_;
00316
int nInternalElems_;
00317
int nOghostElems_;
00318
int nLocalNd_;
00319
int nOGhostNodes_;
00320
int nforig_;
00321
int nBlocks_;
00322
short int nmat_;
00323
short int nen_;
00324
short int ndf_;
00325 AthenaNode *nodes_;
00326 AthenaNode **ghosts_;
00327
int *part_gnode_;
00328
int *fnode_part_;
00329
int *nodeFIDs_;
00330
int *ghostFIDs_;
00331
int *bjacobi_blocks_;
00332
const PromComm &Comm_;
00333 PromOptions &options_;
00334 PromPerfMonitor &perf_mon_;
00335 };
00336
00338
00341 class Athena :
public PromContext
00342 {
00343
public:
00344
Athena(
const PromComm &comm, PromOptions &opts,
00345 PromPerfMonitor &perf );
00346 ~
Athena();
00347
virtual int newPartition(
const int myprocess,
const int nprocess,
00348
const int nparts,
const int startp,
const int stepp,
00349
const int inpgn,
const int inpge,
00350
const PromComm &comm, PromOptions &opts,
00351 PromPerfMonitor &perf, AthenaPartition **pout) = 0;
00352
virtual int newPartition(
const AthenaPartition *part1,
const PromComm &comm,
00353 PromOptions &opts, PromPerfMonitor &perf,
00354 AthenaPartition **pout) = 0;
00355
int Distribute(
char FEPname[256],
int* );
00356
int PostRun();
00357
static int MakeMaps( AthenaPartition *part1, AthenaPartition *part2,
00358
int *&pnode_fnode,
int *&ghost_gnode,
00359
int &npLoc,
int &npGst, MPI_Comm comm,
const int myaddrsp,
00360
const int numaddrsp,
const int mylocalproc,
00361
const int numlocalprocs );
00362
protected:
00363
static int GetGhostMaps(
const int myAnode0,
const int numnd,
00364
const int numndTOT,
const int my0,
00365
const int pnode_fnode[],
const int nforg,
00366
const int fnode_addrsp[],
const int nfaddrsp,
00367
const int anode_lproc[],
const int naLoc,
00368
const int anode_fnode[],
const int npGst,
00369
int ghost_gnode[],
00370
const int myaddrsp,
const int numaddrsp,
00371
const int mylocalproc,
const int numlocalprocs );
00372
public:
00373
00374
int myAddrsp()
const {
return myproc_/proc_asp_; }
00375
int myLocalProc()
const {
return myproc_%proc_asp_; }
00376
int numAddrsp()
const {
00377
int ii = numprocs_/proc_asp_; assert(numprocs_ % proc_asp_ == 0);
00378
00379
return ii;
00380 }
00381
int numLocalProcs()
const {
00382
int left = numprocs_ % proc_asp_, ii = numprocs_ / proc_asp_ ;
00383
return ( left == 0 || myproc_ >= ii * proc_asp_ ) ? proc_asp_ : left ;
00384 }
00385
00386
static int getFstart(
const int nnodes,
const int myp,
const int np );
00387
static int defaultFidPart(
const int nnodes,
const int fid,
const int np );
00388
static int getNewTag(MPI_Comm comm){
00389
int tag; PetscCommGetNewTag( comm, &tag );
00390
return tag;
00391 }
00392
00393 AthenaPartition *part1_;
00394 AthenaPartition *part2_;
00395
00396
int myproc_;
00397
int numprocs_;
00398
int proc_asp_;
00399
const PromComm &Comm_;
00400 PromOptions &options_;
00401 PromPerfMonitor &perf_mon_;
00402 };
00403
00404
00405
00406
00407
class AthenaPartitionFeap :
public AthenaPartition
00408 {
00409
public:
00410 AthenaPartitionFeap(
const int myprocess,
const int nprocess,
00411
const int nparts,
const int startp,
const int stepp,
00412
const int inpgn,
const int inpge,
00413
const PromComm &comm, PromOptions &opts, PromPerfMonitor &perf ):
00414 AthenaPartition( myprocess, nprocess, nparts, startp, stepp,
00415 inpgn, inpge, comm, opts, perf ){}
00416 AthenaPartitionFeap(
const AthenaPartition *part1,
const PromComm &comm,
00417 PromOptions &opts, PromPerfMonitor &perf ) :
00418 AthenaPartition( part1, comm, opts, perf ){}
00419
protected:
00420
virtual int ReadIfile( AthenaFile *Ifile,
int &nTotalNd,
int &nElems,
00421 PromList<AthenaElem*> &elems,
00422 AthenaNode **&inputGhosts );
00423
virtual int Write( AthenaFile *Ifile, AthenaFile *Ofile,
const int nIghost,
00424
const PromTable<int> &fnodes,
00425
const PromTable<AthenaNode*> &ghosts,
00426 PromList<AthenaElem*> &elems);
00427
private:
00428
int getRegion( AthenaFile *Ifile );
00429 };
00430
00431
class AthenaFeap :
public Athena
00432 {
00433
public:
00434 AthenaFeap(
const PromComm &comm, PromOptions &opts,
00435 PromPerfMonitor &perf ) :
Athena( comm, opts, perf ) {}
00436
int newPartition(
const int myprocess,
const int nprocess,
00437
const int nparts,
const int startp,
const int stepp,
00438
const int inpgn,
const int inpge,
00439
const PromComm &comm, PromOptions &opts,
00440 PromPerfMonitor &perf, AthenaPartition **pout ){
00441 AthenaPartition *out;
00442 out =
new AthenaPartitionFeap(myprocess, nprocess, nparts, startp, stepp,
00443 inpgn, inpge, comm, opts, perf );
00444 *pout = out;
00445
return 0;
00446 }
00447
int newPartition(
const AthenaPartition *part1,
const PromComm &comm,
00448 PromOptions &opts, PromPerfMonitor &perf,
00449 AthenaPartition **pout ){
00450
int ierr; AthenaPartition *out;
00451 out =
new AthenaPartitionFeap( part1, comm, opts, perf );
00452 *pout = out;
00453
return 0;
00454 }
00455 };
00456
00457
#endif // __ATHENA_H__