00001
00002
00003
00004
00005
00006
#ifndef __PROMETHEUS_H__
00007
#define __PROMETHEUS_H__
00008
00009
#include "prom_grid.hh"
00010
00011
00012
00013
00014
00015
00016
class PromSolver;
00017
class PromMG;
00019
00022 class Prometheus :
public PromContext
00023 {
00024
public:
00025
Prometheus(
const PromComm &comm, PromOptions &opts,
00026 PromPerfMonitor &perf );
00027 ~
Prometheus();
00028
int Init(
bool init1 );
00029
virtual int Archive( FILE *file = stderr,
00030
const PromArchiveType type = PROM_PRINT);
00032
int NewLevel(
int );
00033
private:
00034
bool allDone(
PromGrid *lastGrid,
const int topMaxEq )
const ;
00035
int MakeNewGrid(
bool islast,
const int topMaxEq,
00036
PromGrid *
const lastGrid,
PromGrid *& newGrid )
const;
00037
public:
00038
int FinalizeSymbolic();
00039
int UpdateGeometry(
double *
const crds,
double *
const deltas );
00040
int SetMatrixWithNewData(
PromMatrix *AA );
00041
int CreateFineGrid(
const int npLoc,
const int lid_ndof[],
const int ndf,
00042
const PromTable<int> &gid_ghostLid,
00043
const PromList<int*> *elemList);
00044
int getNumLevels()
const;
00045
int nBlocksWithGlobalDOF(
const int gl )
const;
00046
int WritePartitioned();
00047
int MakeSplitCoarseGrid(
PromGrid *lastGrid,
const int nloc,
00048
const int nnodes,
PromGrid **newGrid,
00049
const int factor )
const;
00050
int ConvertToSymm(
PromMatrix *
const A,
const PromOptions &opts)
const;
00051 PromMGType getMGType()
const {
return mgType_; }
00052
00053
00054
bool finalized_;
00055 PromMGType mgType_;
00056
PromGrid *top_grid_;
00057
PromGrid *grid0_;
00058
PromVector *D1_2inv_;
00059
PromSolver *solver_;
00060
00061
00062
00063
00064
const PromComm &Comm_;
00065 PromOptions &options_;
00066 PromPerfMonitor &perf_mon_;
00067
PromParentBank parBank_;
00068 };
00069
00070
00071
00072
00074
00078 class PromProjKKTSolver
00079 {
00080
public:
00081
PromProjKKTSolver() : projC_(NULL), CCt_inv_(NULL), workCR_(NULL),
00082 ipiv_(NULL), ksp_mult_work_(NULL), projLEq_geq_(NULL){}
00083 ~
PromProjKKTSolver(){
00084
if( projC_ != NULL ) ClearProjC();
00085
else assert(workCR_ == NULL);
00086 }
00087
int ClearProjC(){
00088 assert(projC_ != NULL);
00089
delete projC_;
delete workCR_;
delete ksp_mult_work_;
00090 PetscFree( ipiv_ ); PetscFree( CCt_inv_ );
00091
if( projLEq_geq_ != NULL ) PetscFree( projLEq_geq_ );
00092
00093 projC_ = NULL;
00094 projLEq_geq_ = ipiv_ = NULL;
00095 CCt_inv_ = NULL;
00096 ksp_mult_work_ = workCR_ = NULL;
00097
return 0;
00098 }
00099
int SetProjC(
const PromMatrix *
const C,
00100 PromTable<int> *projCREqs );
00102
int PreSolve(
const PromMatrix *
const A,
const PromVector*
const,
00103
PromVector *
const bb,
PromVector *
const x_0 )
const;
00104
int PostSolve(
const PromVector *
const x_0,
PromVector*
const xx )
const;
00105
int ComputeMultiplier(
const PromMatrix *
const A,
00106
const PromMatrix *
const otherC,
00107
const PromVector*
const xx,
PromVector*
const pp,
00108
const PromVector *
const bb )
const;
00109
int ApplyProj(
const PromVector *
const XX,
PromVector *
const YY )
const;
00110
int Apply_CCInv_C(
const PromVector *
const XX,
PromVector *
const YY)
const;
00111
int Apply_Ct_CCInv(
const PromVector *
const XX,
PromVector*
const YY)
const;
00112
int Apply_Ct_add(
const PromVector *
const GG,
PromVector *
const XX,
00113
PromVector *
const YY )
const;
00114
int ApplyCCInv(
PromVector *
const XX )
const;
00115
private:
00116
int MapProjCRsToAllCRs(
const PromVector*
const XX,
PromVector*
const YY )
const;
00117
int MapAllCRsToProjCRs(
const PromVector*
const GG,
PromVector *
const YY)
const;
00118
public:
00119
bool isConforming(
const PromVector *
const XX,
double &beta )
const;
00120
static int SparseDot(
const int nz1,
const int ip1[],
const double vv1[],
00121
const int nz2,
const int ip2[],
const double vv2[],
00122
double &dot );
00123
00124
const PromMatrix *projC_;
00125
mutable PromVector *ksp_mult_work_;
00126
private:
00127
double *CCt_inv_;
00128
int *ipiv_;
00129
int *projLEq_geq_;
00130
mutable PromVector *workCR_;
00131 };
00132
00133
00134
00135
00137
00141 class PromSolver
00142 {
00143
friend class PromPCMG;
00144
friend class PromUzawaSolver;
00145
friend class PromMatrix_base;
00146
friend class Prometheus_LinSysCore;
00147
public:
00149 PromSolver(
const PromOptions &opts, PromPerfMonitor &perf,
00150
const PromMap &map,
const PromMap *
const pmap = NULL ) :
00151 options_(opts), perf_mon_(perf), alias_(NULL), pc_(NULL),
00152 rtol_(1.e-5), dtol_(1.e5), atol_(1.e-29), A_(NULL),
00153 nwork_(0),work_(NULL),projector_(NULL),
00154 verbose_(opts.verbose_), cg_restart_(-300), map_(map), p_map_(pmap), alloced_(TRUE),
00155 ksp_type_(PROMKSPGMRES), maxits_(1),nEig_(0){}
00157 PromSolver(
PromSolver *
const solver ) :
00158 options_(solver->options_), perf_mon_(solver->perf_mon_), alias_(solver),
00159 pc_(NULL), rtol_(solver->rtol_), dtol_(solver->dtol_),
00160 atol_(solver->atol_), projector_(NULL),
00161 A_(NULL),nwork_(0),work_(NULL),verbose_(solver->options_.verbose_),
00162 alloced_(FALSE), cg_restart_(-300),
00163 map_(solver->map_),p_map_(solver->p_map_), ksp_type_(PROMNUMKSP),
00164 maxits_(solver->maxits_),nEig_(0)
00165 {
00166 assert(solver != NULL && solver->
alias_ == NULL); solver->
alias_ =
this;
00167 }
00169
~PromSolver();
00170
00171
int SetPC(
PromPC_base *
const pc,
const PromMatrix_base *AA ){
00172 A_ = AA;
00173 assert(pc_==NULL); pc_ = pc;
00174
return 0;
00175 }
00176
int PrintInfo(
const int nactivep,
const int lev = -1 )
const;
00177
int SetUp();
00178
00180
int KSPMult(
const PromMatrix_base *
const A,
00181
const PromVector_base *
const XX,
00182
PromVector_base *
const YY )
const;
00183
int SetTolerances(
const int maxits,
double rtol = -1.,
00184
double atol = -1.,
double dtol = -1. );
00185
int SetGMRESRestart(
int kmax ){ maxits_ = kmax;
return 0; }
00186
00187
int SetNewPVec(
const PromMap &map );
00188
int SetKSPType( PromKSPType type );
00189 PromKSPType getKSPType()
const {
00190 assert(
this != NULL );
00191
if( !alloced_ )
return alias_->
getKSPType();
00192
return ksp_type_;
00193 }
00194
int SetKSP(
const int maxit,
const char*
const prestring = NULL,
00195
const char*
const ksp_string = NULL );
00196
int SetRTol(
double tol ) {
00197 assert(
this!=NULL);
00198 rtol_ = tol;
00199
return 0;
00200 }
00201
double getRTol()
const {
00202 assert(
this!=NULL);
00203
return rtol_;
00204 }
00205
double getATol()
const {
00206 assert(
this!=NULL);
00207
return atol_;
00208 }
00209
int nEig()const{
return nEig_;}
00210
#undef __FUNCT__
00211
#define __FUNCT__ "PromSolver::SetNEig"
00212
int SetNEig(
int nn ) {
00213
if(
this==NULL || nn<=0 )SETERRQ(-1,
"this==NULL || nn<=0");
00214
if( origin_.e != NULL ) {
00215
#if defined(PROM_HAVE_COMPLEX)
00216
PromComplex *pt = dynamic_cast<PromComplex*>(origin_.c);
00217
if( pt != NULL )
delete [] pt;
00218
else {
00219
int ierr = PetscFree( origin_.e ); CHKERRQ(ierr);
00220 }
00221
#else
00222
assert(dd_.e[nEig_+1] == -13.0);
00223
int ierr = PetscFree( origin_.e ); CHKERRQ(ierr);
00224 #endif
00225 origin_.e = d_.e = ee_.e = dd_.e = NULL;
00226 }
00227 nEig_ = nn;
00228
return 0;
00229 }
00230
00231
bool computeSVD()
const {
00232
return ( (nEig() > 0 && ksp_type_ == PROMKSPCG) ||
00233 ksp_type_ == PROMKSPGMRES || ksp_type_ == PROMKSPFGMRES );
00234 }
00235
int SetComputeSVD();
00236
int ComputeExtremeSVD(
int nits,
double &emax,
double &emin );
00237
private:
00238
int ComputeExtremeSVD_cg(
int nn,
double &emax,
double &emin );
00239
int ComputeExtremeSVD_gmres(
int n,
double &emax,
double &emin );
00240
public:
00241
00242
int SolveGMRES(
const PromVector_base *
const,
00243
PromVector_base*
const,
int *its,
00244
const bool zeroguess = TRUE,
00245
const bool avoidnorms = FALSE,
00246
const PromPCSide = PROM_RIGHT );
00247
private:
00248
int ResidualGMRES(
const PromPCSide pc_side,
const PromVector_base *
const xx,
00249
PromVector_base*
const vv_0,
00250
const PromVector_base*
const binvf,
00251
PromVector_base*
const temp );
00252
int CycleGMRES(
const PromPCSide pc_side,
const PromVector_base *
const bb,
00253
PromVector_base *
const xx,
int *reason,
00254
int *itcount,
double *rnorm0,
00255
const bool avoidnorms );
00256
int UpdateGMRESHessenberg(
const int it,
bool hapend,
double *res );
00257
int BuildGMRESSoln(
const PromPCSide pc_side,
double* nrs,
00258
PromVector_base *vdest,
00259
const int it,
const PromVector_base *
const* vv_0,
00260
PromVector_base *
const temp);
00261
int ModifiedGramSchmidtOrthogonalization(
const int it);
00262
int UnmodifiedGramSchmidtOrthogonalization(
const int it);
00263
int TwoUnmodifiedGramSchmidtOrthogonalization(
const int it);
00264
#if defined(PROM_HAVE_COMPLEX)
00265
int UpdateGMRESHessenberg_complex(
const int it,
bool hapend,
double *res );
00266
int BuildGMRESSoln_complex(
const PromPCSide pc_side, PromComplex* nrs,
00267
PromVector_base *vdest,
00268
const int it,
const PromVector_base *
const* vv_0,
00269
PromVector_base *
const temp);
00270
int ModifiedGramSchmidtOrthogonalization_complex(
const int it);
00271
int UnmodifiedGramSchmidtOrthogonalization_complex(
const int it);
00272
int TwoUnmodifiedGramSchmidtOrthogonalization_complex(
const int it);
00273
#endif
00274
int PromResidual(
const PromPCSide pc_side,
const bool zerox,
00275
PromVector_base *vsoln,
PromVector_base *vt1,
00276
PromVector_base *vt2,
PromVector_base *vres,
00277
PromVector_base *vbinvf,
00278
const PromVector_base *
const vb );
00279
int SandwPre(
const double omV[],
const int deg,
PromPC_base *
const pc,
00280
const PromMatrix_base *
const Amat,
PromVector_base *
const xx,
00281
PromVector_base *
const yy,
PromVector_base *
const work)
const;
00282
int SandwPost(
const double omV[],
const int deg,
PromPC_base *
const pc,
00283
const PromMatrix_base *
const Amat,
PromVector_base *
const xx,
00284
PromVector_base *
const yy,
PromVector_base *
const work)
const;
00285
int BrezParameters(
const PromMatrix_base *
const AA,
00286
double &mlsOver,
double &mlsCf,
00287
double &mlsOm,
double &mlsOm2 ) ;
00288
public:
00289
int SolveRichardson(
const PromVector_base*
const,
00290
PromVector_base*
const,
int *its,
00291
const bool zeroguess = TRUE,
00292
const bool avoidnorms = FALSE,
00293
const PromPCSide = PROM_RIGHT );
00294
int SolveBCGS(
const PromVector_base*
const,
00295
PromVector_base*
const,
int *its,
00296
const bool zeroguess = TRUE,
00297
const bool avoidnorms = FALSE,
00298
const PromPCSide = PROM_RIGHT );
00299
int SolveCR(
const PromVector_base*
const,
00300
PromVector_base*
const,
int *its,
00301
const bool zeroguess = TRUE,
00302
const bool avoidnorms = FALSE,
00303
const PromPCSide = PROM_RIGHT );
00304
int SolveBrez(
const PromVector_base*
const,
00305
PromVector_base*
const,
int *its,
00306
const bool zeroguess = TRUE,
00307
const bool avoidnorms = FALSE,
00308
const PromPCSide = PROM_RIGHT );
00309
int SolveCheb(
const PromVector_base*
const,
00310
PromVector_base*
const,
int *its,
00311
const bool zeroguess = TRUE,
00312
const bool avoidnorms = FALSE,
00313
const PromPCSide = PROM_RIGHT );
00314
int SolveCG(
const PromVector_base*
const,
00315
PromVector_base*
const,
int *its,
00316
const bool zeroguess = TRUE,
00317
const bool avoidnorms = FALSE,
00318
const PromPCSide = PROM_RIGHT );
00319
int SolveTFQMR(
const PromVector_base*
const,
00320
PromVector_base*
const,
int *its,
00321
const bool zeroguess = TRUE,
00322
const bool avoidnorms = FALSE,
00323
const PromPCSide = PROM_LEFT );
00324
int SolveSYMMLQ(
const PromVector_base*
const,
00325
PromVector_base*
const,
int *its,
00326
const bool zeroguess = TRUE,
00327
const bool avoidnorms = FALSE,
00328
const PromPCSide = PROM_LEFT );
00329
int SolveMINRES(
const PromVector_base*
const,
00330
PromVector_base*
const,
int *its,
00331
const bool zeroguess = TRUE,
00332
const bool avoidnorms = FALSE,
00333
const PromPCSide = PROM_LEFT );
00334
00335
int CreatePC( PromPCType type,
const PromVector_base *
const v );
00336
int MakePC(
PromGrid *
const grid,
00337
int &nblocks, PromIS *&blockISs,
bool &kspset,
00338
const PromVector *
const xx,
00339
const char*
const prestring = NULL,
00340
const char*
const pcname = NULL );
00341
int SetOperator(
const PromMatrix_base *
const A );
00342
int SetNewOperator(
const PromMatrix_base *
const A );
00343
int SetOperator_private(
const PromMatrix_base *
const A );
00345
int PromPCApplyBAorAB(
const PromMatrix_base *
const Amat,
00346
PromPC_base *
const pc,
00347
const PromPCSide pc_side,
00348
const PromVector_base *
const xx,
00349
PromVector_base *
const dest,
00350
PromVector_base *
const zz )
const;
00352
int Solve(
const PromVector_base*
const bb,
00353
PromVector_base*
const xx,
00354
int *its,
const bool zeroguess = TRUE,
00355
const bool avoidnorms =FALSE);
00356
protected:
00357
int TestSymmMA(
const PromMatrix_base *
const Amat,
00358
PromPC_base *
const pc,
PromVector_base *
const Z,
00359
PromVector_base *
const P,
PromVector_base *
const R )
const;
00360
int Monitor(
const int it,
const double dp ){
00361
if(verbose_>1 || (verbose_==1 && it%5==0)) {
00362
return PetscPrintf(A_->
MPIComm(),
"%d KSP Residual norm %12.7e\n",it,dp);
00363 }
00364
return 0;
00365 }
00366
int converged(
double r0,
double r ){
00367 assert(
this!=NULL);
00368
if( r<r0*rtol_ || r<atol_ )
return 1;
00369
else if ( r > r0*dtol_)
return -1;
00370
return 0;
00371 }
00372
public:
00373
00374
static const char *
const PromKSPStrings[PROMNUMKSP];
00375
00376
PromPC_base *pc_;
00377
const PromMatrix_base *A_;
00378
PromVector_base **work_;
00379
const PromMap &map_;
00380
const PromMap *
const p_map_;
00381
PromProjKKTSolver *projector_;
00382
protected:
00383
PromSolver *alias_;
00384
const PromOptions &options_;
00385 PromPerfMonitor &perf_mon_;
00386
float rtol_;
00387
float dtol_;
00388
float atol_;
00389
const bool alloced_;
00390
public:
00391
mutable short int verbose_;
00392
protected:
00393
short int nwork_;
00394
short int cg_restart_;
00395
struct prom_double_complex{
00396 prom_double_complex(): e(NULL)
00397 #if defined(PROM_HAVE_COMPLEX)
00398 , c(NULL)
00399 #endif
00400 {};
00401
double *e;
00402
#if defined(PROM_HAVE_COMPLEX)
00403
PromComplex *c;
00404
#endif
00405
}origin_, d_, hes_, dd_, ee_;
00406
00407 PromKSPType ksp_type_;
00408
short int nEig_;
00409
short int maxits_;
00410
public:
00411
struct prom_history{
00412 prom_history():helmholtz(0),iters(0),change(-511),level(0),istop(0),isbase(0){}
00413
unsigned int helmholtz : 1;
00414
unsigned int iters : 10;
00415
int change : 10;
00416
unsigned int level : 4;
00417
unsigned int istop : 1;
00418
unsigned int isbase : 1;
00419
unsigned int aux : 5;
00420 }history_;
00421 };
00422
00423
00424
00425
00426
typedef enum BlktypeTAG{PROM_INF=0,PROM_INTER,PROM_INF_SUP,PROM_SUP}PromBlockType;
00427
typedef enum BlkListtypeTAG{PROM_INFL=0,PROM_INTER1,PROM_INTER1B,PROM_INF_SUP_WO_HIGHERIS,PROM_INF_SUPL,PROM_INF_SUP_WO_LOWERIS,PROM_INTER2,PROM_INTER2B,PROM_SUPL,PROM_NBLKLISTTYPES}PromBlockListType;
00428
00429
struct PromGSCont{
00430 PromGSCont():arr_size_(0),list_(NULL){}
00431
int arr_size_;
00432
union{
00433 PromList<int> *list_;
00434
int *array_;
00435 };
00436 };
00437
00438
00439
00440
00441
class PromProcXComm
00442 {
00443
public:
00444 PromProcXComm(
int nn,
int neq,
int ppart, MPI_Comm cm,
const int tg ) :
00445 nNds_(nn),
00446 nEqs_(neq),
00447 part_(ppart),
00448 req_(MPI_REQUEST_NULL),
00449 comm_(cm),
00450 tag_(tg),
00451 lids_(NULL),
00452 xarr_(NULL)
00453 {
00454 assert(nNds_>0);
00455
int isz=
sizeof(
int), dsz=
sizeof(
double), xx=nEqs_*(dsz/isz)+nNds_;
00456 PetscMalloc((xx+1)*isz,&lids_); assert(lids_ != NULL);
00457 lids_[xx] = lids_[xx-1] = -7;
00458 xarr_ = (
double*)(lids_);
00459 xx = nEqs_;
while(xx--) xarr_[xx] = 1.e30;
00460 lids_ += nEqs_ * (dsz/isz);
00461 InfBlocks_.arr_size_ = 0;
00462 InfBlocks_.list_ =
new PromList<int>(10);
00463 }
00464 ~PromProcXComm() {
00465 assert(lids_[nNds_-1] != -7); assert(lids_[nNds_] == -7);
00466 PetscFree( xarr_ );
00467
if(InfBlocks_.arr_size_ != 0) PetscFree(InfBlocks_.array_);
00468 }
00469
00470
const int part_;
00471
const int nNds_;
00472
const int nEqs_;
00473
const int tag_;
00474 PromGSCont InfBlocks_;
00475
int *lids_;
00476
double *xarr_;
00477 MPI_Request req_;
00478 MPI_Comm comm_;
00479 };
00480
00481
00482
00483
00484
class PromBlockXComm
00485 {
00486
public:
00487 PromBlockXComm(
int nn,
int neq,
int ppart,
const int ggbid ) :
00488 nNds_(nn),
00489 nEqs_(neq),
00490 part_(ppart),
00491 #if defined(PROM_MEASURE_MPATH)
00492 path_(-9999),
00493 #endif
00494 gbid_(ggbid)
00495 {
00496 assert(nNds_>0);
int isz =
sizeof(
int);
00497 PetscMalloc((nNds_+1)*isz,&locBoundIDs_); assert(locBoundIDs_!=NULL);
00498 locBoundIDs_[nNds_] = locBoundIDs_[nNds_-1] = -7;
00499 }
00500 ~PromBlockXComm() {
00501 assert(locBoundIDs_[nNds_-1] != -7 && locBoundIDs_[nNds_] == -7);
00502 PetscFree(locBoundIDs_);
00503 }
00504
00505
int *locBoundIDs_;
00506
const int nEqs_;
00507
const int nNds_;
00508
const int part_;
00509
const int gbid_;
00510
#if defined(PROM_MEASURE_MPATH)
00511
int path_;
00512
#endif
00513
};
00514
00515
00516
00517
00518
class PromGSBlock
00519 {
00520
public:
00521 PromGSBlock(
int iidd,
int pproc ) :
00522 #if defined(PROM_MEASURE_MPATH)
00523 path_(-8888),
00524 #endif
00525 proc(pproc)
00526 {
00527 bits.done = FALSE; bits.gid = iidd;
00528 }
00529
virtual ~PromGSBlock(){}
00530
int getProc()
const { assert(
this!=NULL);
return proc; }
00531
int isMarked()
const { assert(
this!=NULL);
return bits.done; }
00532
void mark(
int b = 1 ){ assert(
this!=NULL); bits.done = (b==0) ? 0 : 1; }
00533
int getGBID()
const { assert(
this!=NULL);
return bits.gid; }
00534
00535
#if defined(PROM_MEASURE_MPATH)
00536
int path_;
00537
#endif
00538
private:
00539
00540
struct {
00541
unsigned int done : 1;
00542
unsigned int gid : 31;
00543 }bits;
00544
const int proc;
00545 };
00546
00547
00548
00549
00550
class PromInfSupBlock :
public PromGSBlock
00551 {
00552
public:
00553 PromInfSupBlock(
int iidd,
int pproc ) :
00554 PromGSBlock(iidd,pproc),
00555 high_ISBlocks_(10),
00556 low_ISBlocks_(10),
00557 ISBlockDeps_(NULL),
00558 lowProc_sendXComm_(10),
00559 highProc_sendXComm_(10),
00560 sendXComm_(NULL)
00561 {
00562 }
00563 ~PromInfSupBlock(){
00564 PromBlockXComm *commx;
00565
while ( !highProc_sendXComm_.isEmpty() ) {
00566 commx = highProc_sendXComm_.removeHead();
00567
delete commx;
00568 }
00569
while ( !lowProc_sendXComm_.isEmpty() ) {
00570 commx = lowProc_sendXComm_.removeHead();
00571
delete commx;
00572 }
00573 }
00574
int collectSends( PromTable<PromList<PromBlockXComm*>*> &proc_list );
00575 PromList<PromGSBlock*> *ISBlockDeps_;
00576 PromList<PromBlockXComm*> *sendXComm_;
00577
00578 PromList<PromGSBlock*> high_ISBlocks_;
00579 PromList<PromGSBlock*> low_ISBlocks_;
00580
00581 PromList<PromBlockXComm*> lowProc_sendXComm_;
00582 PromList<PromBlockXComm*> highProc_sendXComm_;
00583 };
00584
00585
template <
class T>
class PromAList :
public PromList<T>
00586 {
00587
public:
00588 PromAList(
int sz = 5) : PromList<T>(sz), count_(0) {}
00589
int count_;
00590 };
00591
00592
00593
00594
00595
class PromGSNode
00596 {
00597
public:
00598 PromGSNode(
int lid,
int gid,
unsigned int n=0) : b(lid,n), gid_(gid) {}
00599
int global()
const {
return gid_; }
00600
int nb()const{
return b.multi_;}
00601
00602
struct T{
00603 T(
int l,
unsigned int n):lid_(l),multi_(n){}
00604
const unsigned int multi_ : 4;
00605
const int lid_ : 28;
00606 }b;
00607
private:
00608
const int gid_;
00609 };
00610
00611
00612
00613
00615
00618 class PromPCGaussSeidel :
public PromPC_base
00619 {
00620
friend class PromSolver;
00621
public:
00622
PromPCGaussSeidel(
const PromOptions &opt,
00623 PromPerfMonitor &perf );
00624
int Create(
const PromMatrix *
const,
const PromIS *
const domainISs,
00625
const int nblocks );
00626 ~
PromPCGaussSeidel();
00627
00628
private:
00629
int Create_private(
const PromIS *
const domainISs );
00630
public:
00631
virtual int Apply_private(
const PromVector_base*
const bb,
00632
PromVector_base*
const xx,
const bool zerox=TRUE);
00633
virtual int SetUp_private();
00634 virtual const char *
getPCString()
const {
00635
return PromPCStrings[PROMPCGAUSSSEIDEL + (symmetric_ ? 1 : 0) ];
00636 }
00637
virtual const char * getSubPCString()
const {
00638
if( kkt_ != NULL )
return kkt_->getPCString();
00639
else if( pc_ != NULL )
return pc_->
getPCString();
00640
else return PromPCStrings[PROMPCNONE];
00641 }
00642
virtual int getNumBlocks()
const {
00643
if( pc_ != NULL )
return pc_->
getNumBlocks();
00644
else if( kkt_ != NULL )
return kkt_->getNumBlocks();
00645
else return 0;
00646 }
00647
virtual PromPCType getType()
const {
00648 assert(
this != NULL );
00649
return PROMPCGAUSSSEIDEL;
00650 }
00651
virtual int takeNonZeroGuess()const{
return pre_smooth_ ? 1 : -1; }
00652
virtual int SetNewOperator_private(
const PromMatrix_base *
const Ab ) {
00653 assert(
this!=NULL);
int ierr; assert(Ab!=NULL);
00654
const PromMatrix *AA = dynamic_cast<const PromMatrix*>(Ab);
00655 assert(AA!=NULL);
00656
if( pc_ != NULL ) {
00657 ierr = pc_->
SetNewOperator( AA ); CHKERRQ(ierr);
00658 }
00659
if( A_ != NULL && AA->
map_ != A_->
map_ )SETERRQ(1,
"A->map_ != map_");
00660 A_ = AA;
00661
return 0;
00662 }
00663
virtual int SetOperator_private(
const PromMatrix_base *
const Ab ) {
00664 assert(
this!=NULL);
int ierr; assert(Ab!=NULL);
00665
const PromMatrix *AA = dynamic_cast<const PromMatrix*>(Ab);
00666 assert(AA!=NULL);
00667
if( pc_ != NULL ) {
00668 ierr = pc_->
SetOperator( AA ); CHKERRQ(ierr);
00669 }
00670
if( A_ != NULL && AA->
map_ != A_->
map_ )SETERRQ(1,
"A->map_ != map_");
00671 A_ = AA;
00672
return 0;
00673 }
00674
private:
00675
int Apply_one(
const PromVector*
const bb,
PromVector*
const xx,
00676
bool zerog = FALSE,
bool send_post = TRUE );
00677
00678
virtual int Setup_private( PromList<int> **
const block_procs,
00679 PromTable<int> **
const block_gid_ghostLid,
00680 PromList<int> **block_nodeLids,
00681 PromList<int> **block_boundLids,
00682 PromList<int> **block_adjacBLids,
00683 PromTable<PromTable<int>*>*
const proc_boundNodes,
00684
const PromIS *
const domainISs,
00685 PromList<int> *highlist,
00686 PromList<int> *lowlist );
00687
int ColorProcs(PromList<int> *
const highlist, PromList<int> *
const lowlist);
00688
int SetBlockTypes(
const PromList<int> *
const *
const block_procs,
00689
const PromTable<PromTable<int>*>*
const proc_bNodes,
00690 PromBlockType block_type[],
int lid_blockGID[],
00691
const PromIS *
const domainISs );
00692
int MakeLists( PromList<int> *
const *
const block_procs,
00693
const PromTable<int> *
const *
const block_ghosts,
00694
const PromBlockType block_type[],
const int lid_blockGID[],
00695
const PromList<int> *
const *
const block_nodeLids,
00696
const PromList<int> *
const *
const block_boundNodes,
00697
const PromList<int> *
const *
const block_adajacBlids,
00698
const PromIS*
const domainISs);
00699
int SetupNodalGS();
00700
00701
int DoBlocks(
const int nb,
const int blocks[],
00702
const PromVector*
const bb,
00703
PromVector *
const xx )
const;
00704
#if defined(PROM_USE_PETSC)
00705
int DoBlocks_nodal_1(
const int nb,
const int block[],
00706
const PromVector*
const b,
00707
PromVector*
const x)
const;
00708
int DoBlocks_nodal_3(
const int nb,
const int block[],
00709
const PromVector*
const bb,
00710
PromVector*
const xx)
const;
00711
int DoBlocks_nodal_6(
const int nb,
const int block[],
00712
const PromVector*
const bb,
00713
PromVector*
const xx)
const;
00714
int DoBlocks_nodal(
const int nb,
const int block[],
00715
const PromVector*
const bb,
PromVector*
const xx,
00716
const int ndf )
const;
00717
int DoBlocks_schwarz_1(
const int nb,
const int block[],
00718
const PromVector*
const bb,
00719
PromVector*
const xx,
00720
const PromPC *
const pc )
const;
00721
int DoBlocks_schwarz_3(
const int nb,
const int block[],
00722
const PromVector*
const bb,
00723
PromVector*
const xx,
00724
const PromPC *
const pc )
const;
00725
int DoBlocks_schwarz_6(
const int nb,
const int block[],
00726
const PromVector*
const bb,
00727
PromVector*
const xx,
00728
const PromPC *
const pc )
const;
00729
int DoBlocks_schwarz(
const int nb,
const int block[],
00730
const PromVector*
const bb,
PromVector*
const xx,
00731
const PromPC *
const pc,
00732
const int ndf )
const;
00733
#else
00734
00735
#endif
00736
00737
00738
int GetProc(
const int gid,
int &proc )
const;
00739
int PostRecvs(
const PromAList<PromProcXComm*> *commxList )
const;
00740
int SendLocalx(
const PromList<PromProcXComm*> *commxList,
00741
const PromVector *
const xx)
const;
00742
int RecvDoGhostx( PromAList<PromProcXComm*> *
const commxList,
00743
const PromVector*
const bb = NULL,
00744
PromVector *
const xx = NULL )
const;
00745
int WaitForList(
const PromList<PromProcXComm*> *commxList )
const;
00746
int SendISblocks( PromTable<PromList<PromBlockXComm*>*> *proc_list,
00747 PromList<MPI_Request*> *smessages,
00748
const PromVector *
const xx,
const int tag )
const;
00749
int RecvBlockGhostx(
double ghostx[],
const int nghostEqs,
00750
const int tag,
const bool iprobe,
00751
int &ndone )
const;
00752
public:
00753
int ReorderNodes(
double wieghts[],
int len );
00754
private:
00755
static int BfsReorder( PromList<int> *blidList,
00756
const PromList<int> *
const *
const block_adjacBLids,
00757 PromList<int> *list, PromList<int> *nextRoots,
00758
bool buff1[],
bool buff2[],
const bool print = FALSE);
00759
00760
int maxnGSBlocks_;
00761
00762
public:
00763
int nGSBlocks_;
00764
int bs_;
00765
bool pre_smooth_;
00766
bool symmetric_;
00767 MPI_Comm comm_;
00768
00769
00770
double *NodalFactors_;
00771
double *ghostx_;
00772
int *NodalFactorPointers_;
00773
PromPC *pc_;
00774
const PromMatrix *A_;
00775
private:
00776 PromTable<PromGSNode*> gbid_ghost_;
00777 PromGSCont blocksLists_[PROM_NBLKLISTTYPES];
00778 PromList<PromProcXComm*> lowProc_send_;
00779 PromAList<PromProcXComm*> lowProc_recv_;
00780 PromAList<PromProcXComm*> highProc_recv_;
00781 PromList<PromProcXComm*> highProc_send_;
00782 PromTable<PromGSBlock*> gbid_ISBlock_;
00783 PromTable<int> proc_color_;
00784 };
00785
00786
00787
00788
00790
00793 class PromMG
00794 {
00795
friend class PromPCMG;
00796
friend class Prometheus_LinSysCore;
00797
public:
00798
PromMG( PromPerfMonitor &perf );
00799 ~
PromMG();
00800
00801
int SetCycles(
int nn){ assert(
this!=NULL); cycles_ = nn;
return 0; }
00802
int getCycles()
const{ assert(
this!=NULL);
return cycles_; }
00803
int Create(
PromGrid *
const grid0,
int npre,
int npost,
00804
const PromMap *
const p_map = NULL,
00805
const bool use_iter_on_top = FALSE );
00806
int SetOperator(
const PromMatrix_base *
const K ) {
00807 A_ = K;
int ierr;
00808
if( presmooth_ != NULL ) ierr = presmooth_->
SetOperator( K );
00809
if( postsmooth_ != NULL ) ierr = postsmooth_->
SetOperator( K );
00810 CHKERRQ(ierr);
00811
return 0;
00812 }
00813
int SetNewOperator(
const PromMatrix_base *
const K ) {
00814 A_ = K;
int ierr;
00815
if( presmooth_ != NULL ) ierr = presmooth_->
SetNewOperator(K);
00816
if( postsmooth_ != NULL ) ierr = postsmooth_->
SetNewOperator(K);
00817 CHKERRQ(ierr);
00818
return 0;
00819 }
00820
int SetNewPVec(
const PromMap &map );
00821
00822
PromSolver *presmooth_;
00823
PromSolver *postsmooth_;
00824
PromVector_base *b_;
00825
PromVector_base *x_;
00826
PromVector_base *r_;
00827
const PromMatrix_base *interpolate_;
00828
const PromMatrix_base *restrct_;
00829
const PromMatrix_base *A_;
00830
PromMG *prev_;
00831
PromMG *next_;
00832
int factor_;
00833
protected:
00834 PromPerfMonitor &perf_mon_;
00835
int cycles_;
00836 };
00837
00838
00839
00840
00842
00845 class PromPCMG :
public PromPC_base
00846 {
00847
public:
00848
PromPCMG(
const PromOptions &opts, PromPerfMonitor &perf ) :
00849
PromPC_base( opts, perf ), mgstack_(NULL) {}
00850
virtual ~
PromPCMG();
00851
00852 PromPCType getType()
const {
00853 assert(
this != NULL );
00854
return PROMPCMG;
00855 }
00856
00857
int Apply_private(
const PromVector_base*
const bb,
00858
PromVector_base*
const xx ,
const bool zerox = TRUE );
00859
virtual int SetUp_private();
00860 const char *
getPCString()
const {
00861
return PromPCStrings[PROMPCMG];
00862 }
00863
const char * getSubPCString()
const {
00864
if( kkt_ != NULL )
return kkt_->getPCString();
00865
return PromPCStrings[PROMPCNONE];
00866 }
00867
virtual int SetOperator_private(
const PromMatrix_base *
const K ) {
00868 assert(
this!=NULL);
int ierr;
00869
if( mgstack_ != NULL ) {
00870 ierr = mgstack_->
SetOperator( K ); CHKERRQ(ierr);
00871 }
00872
return 0;
00873 }
00874
virtual int SetNewOperator_private(
const PromMatrix_base *
const K ) {
00875 assert(
this!=NULL);
int ierr;
00876
if( mgstack_ != NULL ) {
00877 ierr = mgstack_->
SetNewOperator( K ); CHKERRQ(ierr);
00878 }
00879
return 0;
00880 }
00881
int PrintLevelInfo() const;
00882
int Create(
PromGrid * const grid0, const
PromMap *p_map = NULL );
00883 private:
00884
int ACycle(
PromMG * const mg, const
bool zerox = TRUE );
00885
int MCycle(
PromMG * const mg,
int level, const
bool zerox = TRUE );
00886
int FCycle(
PromMG * const mg, const
bool zerox = TRUE );
00887 public:
00888
00889
PromMG* mgstack_;
00890 PromMGAlgo algo_;
00891 };
00892
00893
00894
00895
00897
00900 class
PromPCNodalASM : public
PromPC_base
00901 {
00902
public:
00904 PromPCNodalASM(
const PromOptions &opts, PromPerfMonitor &perf )
00905 : PromPC_base(opts,perf),invBlocks_(NULL),A_(NULL),r_(NULL),work_(NULL){}
00907 ~
PromPCNodalASM(){
00908
if( invBlocks_ ) PetscFree( invBlocks_ );
00909
if( r_ )
delete r_;
00910
if( work_ )
delete work_;
00911 }
00913 virtual PromPCType getType()
const {
00914 assert(
this != NULL );
00915
return PROMPCNODALASM;
00916 }
00917 virtual const char *
getPCString()
const {
00918
return PromPCStrings[PROMPCNODALASM];
00919 }
00920
virtual const char * getSubPCString()
const {
00921
if( kkt_ != NULL )
return kkt_->getPCString();
00922
return PromPCStrings[PROMPCNONE];
00923 }
00925 virtual int SetOperator_private(
const PromMatrix_base *
const AA_b ) {
00926 assert(
this!=NULL);
00927
if( AA_b == NULL ) SETERRQ(1,
"AA_b == NULL");
00928
const PromMatrix *
const AA = dynamic_cast<const PromMatrix*>(AA_b);
00929
if(AA==NULL)SETERRQ(1,
"A not a PromMatrix");
00930 A_ = AA;
00931
return 0;
00932 }
00934 virtual int SetNewOperator_private(
const PromMatrix_base *
const AA_b ) {
00935 assert(
this!=NULL);
00936
if( AA_b == NULL ) SETERRQ(1,
"AA_b == NULL");
00937
const PromMatrix *
const AA = dynamic_cast<const PromMatrix*>(AA_b);
00938
if(AA==NULL)SETERRQ(1,
"A not a PromMatrix");
00939 A_ = AA;
00940
00941
return 0;
00942 }
00944
int Create();
00945
int SetUp_private();
00946
virtual int GetOperator(
const PromMatrix **K_out,
00947
PromVector **r_out,
const PromVector_base*
const XX)
00948 {
00949
if( work_ == NULL ) {
00950 work_ =
new PromVector( XX ); assert(r_==NULL);
00951 r_ =
new PromVector( XX );
00952 }
00953 *K_out = A_; *r_out = work_;
00954
return 0;
00955 }
00957
virtual int Apply_private(
const PromVector_base*
const bb,
00958
PromVector_base*
const xx,
const bool zerox = TRUE);
00959
private:
00960
int Apply_one(
const PromVector*
const bb,
PromVector*
const xx );
00961
00962
double *invBlocks_;
00963
PromVector *r_;
00964
PromVector *work_;
00965
const PromMatrix *A_;
00966 };
00967
00968
#endif //__PROMETHEUS_H__