00001
00002
00003
00004
00005
00006
#ifndef __PROM_PETSC_H__
00007
#define __PROM_PETSC_H__
00008
00009
#if defined(PROM_USE_C_PETSC)
00010
extern "C" {
00011
#endif
00012
00013
#include "src/vec/impls/mpi/pvecimpl.h"
00014
00015
#include "src/ksp/pc/impls/mg/mgimpl.h"
00016
#include "src/ksp/ksp/impls/cg/cgctx.h"
00017
#include "petscksp.h"
00018
#include "petscmg.h"
00019
#include "petscpc.h"
00020
#include "petscmat.h"
00021
#include "src/mat/impls/baij/mpi/mpibaij.h"
00022
#include "src/mat/impls/sbaij/mpi/mpisbaij.h"
00023
#include "src/mat/impls/aij/mpi/mpiaij.h"
00024
00025
#if defined(PROM_USE_C_PETSC)
00026
}
00027
#endif
00028
00029
typedef IS PromIS;
00030
00031
#include "prom_base.hh"
00032
00034
#define PromISGetSize ISGetLocalSize
00035
#define PromISGetIndices ISGetIndices
00036
#define PromISRestoreIndices ISRestoreIndices
00037
#define PromISCreateGeneral ISCreateGeneral
00038
#define PromISDestroy ISDestroy
00039
00040
#undef __FUNCT__
00041
#define __FUNCT__ "PromComm"
00042
00043 class PromComm :
public PromComm_base
00044 {
00045
public:
00046
PromComm( MPI_Comm comm ) : mpi_comm_( comm ) {
00047 assert(mpi_comm_!=MPI_COMM_NULL); assert(mpi_comm_!=MPI_COMM_WORLD);
00048 }
00049 MPI_Comm operator()()
const {
return mpi_comm_; }
00050 MPI_Comm MPIComm()
const {
return mpi_comm_; }
00051
int mype()
const {
00052
int tt; assert(mpi_comm_ != MPI_COMM_NULL);
00053 MPI_Comm_rank( mpi_comm_, &tt);
00054
return tt;
00055 }
00056
int np()
const{
00057 assert(mpi_comm_!=MPI_COMM_NULL);
int tt;
00058 MPI_Comm_size(mpi_comm_,&tt);
00059
return tt;
00060 }
00061
int getNewTag()
const {
00062
int tag; PetscCommGetNewTag( mpi_comm_, &tag );
return tag;
00063 }
00064
int getNewTag(MPI_Comm comm)
const {
00065
int tag; PetscCommGetNewTag( comm, &tag );
return tag;
00066 }
00067
const MPI_Comm mpi_comm_;
00068 };
00069
00070
#undef __FUNCT__
00071
#define __FUNCT__ "PromMap"
00072
00073 class PromMap :
public PromMap_base
00074 {
00075
friend class PromMatrix;
00076
public:
00077
PromMap(
int nloc,
const int ElementSize,
const PromComm &comm )
00078 : PromMap_base(nloc,ElementSize*nloc,comm), bsize_(ElementSize),
00079 id_leq_(NULL) {}
00080
PromMap(
int nloc,
const PromComm &comm,
const int nloceq )
00081 : PromMap_base(nloc,nloceq,comm), bsize_(-1), id_leq_(NULL) {}
00082
PromMap(
int nloc,
const int *ElementSizeList,
const PromComm &comm )
00083 :PromMap_base(nloc, sumeqs(nloc,ElementSizeList),comm), bsize_(-1),
00084 id_leq_(NULL) {
00085 SetLidLeq( ElementSizeList );
00086 }
00087
protected:
00088
int SetLidLeq(
const int *ElementSizeList ) {
00089
int ii,jj,tt,s2,r2,nloc=nlocal();
00090
00091
if( nloc > 0 ) {
00092
for(ii=1,tt=ElementSizeList[0];ii<nloc;ii++) {
00093
if(ElementSizeList[ii] != tt)
break;
00094 }
00095
if( ii != nloc ) s2 = tt = 0;
00096
else s2 = tt;
00097 }
00098
else{ s2 = 0; tt = 999; }
00099 MPI_Allreduce(&tt, &jj, 1, MPI_INT, MPI_MIN, comm_() );
00100 MPI_Allreduce(&s2, &r2, 1, MPI_INT, MPI_MAX, comm_() );
00101
const bool constndf = (jj==r2 && jj>0);
const int ndf = jj;
00102
if( constndf ) bsize_ = ndf;
00103
else{
00104 PetscMalloc(
sizeof(
int)*(nloc+1),&id_leq_);
00105
for(ii=0,id_leq_[0] = 0 ; ii < nloc ; ii++ ){
00106 id_leq_[ii+1] = id_leq_[ii] + ElementSizeList[ii];
00107 assert(ElementSizeList[ii]>0);
00108 }
00109 }
00110
return 0;
00111 }
00112
00113
static int sumeqs(
const int nloc,
const int *ElementSizeList ){
00114
int ii,cc;
00115
for(ii = cc = 0 ; ii < nloc ; ii++ )cc += ElementSizeList[ii];
00116
return cc;
00117 }
00118
public:
00119
virtual ~
PromMap() {
00120
if( id_leq_ != NULL ) PetscFree( id_leq_ );
00121 }
00122
00123
int nlocal()
const {
00124 assert(
this!=NULL);
00125
int mype = comm_.mype();
00126
return (proc_gnode_[mype+1] - proc_gnode_[mype]);
00127 }
00128
int nglobal()
const {
00129 assert(
this!=NULL);
00130
int np = comm_.np();
00131
return (proc_gnode_[np]);
00132 }
00133
int nlocalEq()
const {
00134 assert(
this!=NULL);
00135
int mype = comm_.mype();
00136
return (proc_geq_[mype+1] - proc_geq_[mype]);
00137 }
00138
int nglobalEq()
const {
00139 assert(
this!=NULL);
00140
int np = comm_.np();
00141
return proc_geq_[np];
00142 }
00143
bool isConstNDF()
const { assert(
this!=NULL && bsize_ != 0);
return (bsize_>0); }
00144
int constNDFSize()
const { assert(
this!=NULL && bsize_>0);
return bsize_; }
00145
int locID_ndf(
const int i)
const{
00146 assert(
this);
00147
return (bsize_>0) ? bsize_ : id_leq_[i+1] - id_leq_[i];
00148 }
00149
private:
00150
int *id_leq_;
00151
short int bsize_;
00152 };
00153
00154
#undef __FUNCT__
00155
#define __FUNCT__ "PromVector"
00156
00157
00160 class PromVector :
public PromVector_base
00161 {
00162
friend class PromMatrix;
00163
friend class PromPC;
00164
friend class PromZRP;
00165
friend class PromSmoother;
00166
friend class Prometheus;
00167
friend class pFEAP;
00168
friend class PromPCGaussSeidel;
00169
friend class PromPCKKT_ASM;
00170
public:
00172 PromVector(
const PromMap &map,
const int fact = 1 ) :
00173
vec_(NULL),
PromVector_base(map)
00174 {
00175 PetscFunctionBegin;
00176 VecCreateMPI(map.comm_(),map.
nlocalEq()*fact,map.
nglobalEq()*fact,&
vec_);
00177 assert(
vec_ != NULL);
00178
#if defined(PETSC_USE_BOPT_g)
00179
double b=1.e206;
00180 VecSet(&b,
vec_);
00181
#endif
00182
PetscStackPop;
00183 }
00185 PromVector(
const PromVector_base *
const vec_b ) :
00186
vec_(NULL),
PromVector_base( vec_b->map_ ) {
00187
const PromVector *vec = dynamic_cast<const PromVector*>(vec_b);
00188 assert(vec!=NULL);
00189 PetscFunctionBegin;
00190
int ierr = VecDuplicate( vec->
vec_, &
vec_ ); assert(ierr==0);
00191 PetscStackPop;
00192 }
00194 virtual ~PromVector(){
00195
00196 VecDestroy(
vec_);
vec_ = NULL;
00197 }
00199 virtual int GetArray(
double **arr )
const {
00200 assert(
this!=NULL);
00201
return VecGetArray(
vec_, arr );
00202 }
00203
virtual int RestoreArray(
double **arr )
const {
00204 assert(
this!=NULL);
00205
return VecRestoreArray( vec_, arr );
00206 }
00207
virtual double operator[](
int i)
const {
00208
double *arr, tmp; assert(
this!=NULL);
00209
int ierr = VecGetArray( vec_, &arr ); CHKERRQ(ierr);
00210 tmp = arr[i];
00211 ierr = VecRestoreArray( vec_, &arr ); CHKERRQ(ierr);
00212
return tmp;
00213 }
00214
virtual int Set(
double val ){
00215 assert(
this!=NULL);
00216
return VecSet( &val, vec_ );
00217 }
00218
virtual int Scale(
double val ) {
00219 assert(
this!=NULL);
00220
return VecScale( &val, vec_ );
00221 }
00222
virtual int Sqrt(){
00223 assert(
this!=NULL);
00224
int ierr = VecSqrt( vec_ ); CHKERRQ(ierr);
00225
return 0;
00226 }
00227
virtual int Dot(
const PromVector_base *
const b,
double *
const dot)
const{
00228 assert(
this!=NULL);
00229
const PromVector *vec = dynamic_cast<const PromVector*>(b);
00230 assert(vec!=NULL);
00231
return VecDot( vec_, vec->
vec_, dot );
00232 }
00233
virtual int SetValues(
const int nrow,
int *rowp,
const double *vals,
00234
const int add_type ){
00235 assert(
this!=NULL);
00236
return VecSetValues( vec_, nrow, rowp, vals, (InsertMode)add_type );
00237 }
00238
virtual int Norm2(
double *
const norm )
const {
00239 assert(
this!=NULL); PetscScalar nn;
00240
int ierr = VecNorm( vec_, NORM_2, &nn ); *norm = (
double)nn;
00241
return ierr;
00242 }
00243
virtual int NormMax(
double *
const norm )
const {
00244 assert(
this!=NULL); PetscScalar nn;
00245
int ierr = VecNorm( vec_, NORM_MAX, &nn ); *norm = (
double)nn;
00246
return ierr;
00247 }
00248
virtual int Copy(
const PromVector_base *
const pvec ) {
00249
const PromVector *vec = dynamic_cast<const PromVector*>(pvec);
00250 assert(vec!=NULL);
00251
int ierr = VecCopy( vec->
vec_, vec_ ); CHKERRQ(ierr);
00252
return 0;
00253 }
00254 virtual int AXPBY(
double a,
double b,
const PromVector_base *
const X ) {
00255 assert(
this!=NULL);
00256
const PromVector *vec = dynamic_cast<const PromVector*>(X);
00257 assert(vec!=NULL);
00258
return VecAXPBY( &a, &b, vec->
vec_,
vec_ );
00259 }
00261 virtual int AYPX(
double a,
const PromVector_base *
const X ) {
00262
const PromVector *vec = dynamic_cast<const PromVector*>(X);
00263 assert(vec!=NULL);
00264
int ierr = VecAYPX( &a, vec->
vec_,
vec_ ); CHKERRQ(ierr);
00265
return 0;
00266 }
00268 virtual int AXPY(
double a,
const PromVector_base *
const X ) {
00269
const PromVector *vec = dynamic_cast<const PromVector*>(X);
00270 assert(vec!=NULL);
00271
int ierr = VecAXPY( &a, vec->
vec_,
vec_ ); CHKERRQ(ierr);
00272
return 0;
00273 }
00274 virtual int WAXPY(
double alpha,
const PromVector_base *
const X,
00275
const PromVector_base *
const Y ) {
00276 assert(
this!=NULL);
00277
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00278
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00279
return VecWAXPY( &alpha, x->
vec_, y->
vec_,
vec_ );
00280 }
00281 virtual int MAXPY(
const int nv,
double alpha[],
const PromVector_base *
const*Xarr){
00282 assert(
this!=NULL); assert(nv<1000); assert(Xarr!=NULL);
00283 Vec varr[1000];
00284
for(
int i=0;i<nv;i++){
00285
const PromVector *vv = dynamic_cast<const PromVector*>(Xarr[i]);
00286 assert(vv!=NULL); varr[i] = vv->
vec_;
00287 }
00288
return VecMAXPY( nv, alpha,
vec_, varr );
00289 }
00290
virtual int MDot(
const int nv,
const PromVector_base *
const*Xarr,
double arr[])
const{
00291 assert(
this!=NULL); assert(nv<1000); assert(Xarr!=NULL);
00292 Vec varr[1000];
00293
for(
int i=0;i<nv;i++){
00294
const PromVector *vv = dynamic_cast<const PromVector*>(Xarr[i]);
00295 assert(vv!=NULL); varr[i] = vv->
vec_;
00296 }
00297
return VecMDot( nv, vec_, varr, arr );
00298 }
00299
virtual int Assembly(){
00300 assert(
this!=NULL);
00301
int ierr = VecAssemblyBegin( vec_ ); CHKERRQ(ierr);
00302
return VecAssemblyEnd( vec_ );
00303 }
00304 virtual int PointwiseMult(
const PromVector_base *
const X,
00305
const PromVector_base *
const Y){
00306 assert(
this!=NULL);
00307
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00308
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00309
return VecPointwiseMult( x->
vec_, y->
vec_,
vec_ );
00310 }
00311 virtual int PointwiseDiv(
const PromVector_base *
const X,
00312
const PromVector_base *
const Y ) {
00313 assert(
this!=NULL);
00314
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00315
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00316
return VecPointwiseDivide( x->
vec_, y->
vec_,
vec_ );
00317 }
00318 virtual int Reciprocal() {
00319 assert(
this!=NULL);
00320
return VecReciprocal(
vec_ );
00321 }
00322
virtual int getN()
const {
return vec_->N; }
00323
virtual int getn()
const {
return vec_->n; }
00324
virtual int my0()
const {
return map_.my0Eq(); }
00326
protected:
00327 Vec
vec_;
00328 };
00329
00330
#undef __FUNCT__
00331
#define __FUNCT__ "PromMatrix"
00332
00333
00336 class PromMatrix :
public PromMatrix_base
00337 {
00338
friend class PromPC;
00339
friend class PromMG;
00340
friend class Prometheus;
00341
friend class PromContext;
00342
friend class PromPCGaussSeidel;
00343
friend class PromPCKKT_ASM;
00344
friend class PromCRMatrix;
00345
public:
00347
PromMatrix(
const PromGrid *grid,
int nA,
int *pnA,
int nB,
int *pnB,
int fact=1);
00349
PromMatrix(
const PromMap &map,
int nA,
int *pnA,
int nB,
int *pnB,
00350
int lcols = -1,
int gcols = -1,
int fact=1);
00352
virtual int SetUp(
int nA,
int *pnA,
int nB,
int *pnB,
int lcols,
int gcols,
int fact=1);
00354 PromMatrix(
const PromMatrix_base* B ) :
00355
mat_(NULL), full_mat_(NULL), varray_(NULL), varr_sz_(0),
00356 array_(NULL), ghostGID_BID_(NULL), ghostGID_ndf_(NULL),
00357 ghostBID_GID_(NULL),
PromMatrix_base( B->map_ ) {
00358
const PromMatrix *A = dynamic_cast<const PromMatrix*>(B); assert(A!=NULL);
00359 MatDuplicate( A->
mat_, MAT_COPY_VALUES, &
mat_ );
00360 }
00362 PromMatrix(
const PromMap &cmap, Mat a ) :
00363
mat_(a), varray_(NULL), full_mat_(NULL),
00364 varr_sz_(0), array_(NULL), ghostGID_BID_(NULL), ghostGID_ndf_(NULL),
00365
PromMatrix_base( cmap ), ghostBID_GID_(NULL) {}
00367 virtual int Transpose(
const PromMap &cmap,
PromMatrix_base **out )
const {
00368 assert(
this!=NULL); assert(0);
00369
int ierr; Mat aa;
00370 ierr = MatTranspose(
mat_, &aa ); CHKERRQ(ierr);
00371
PromMatrix *trans =
new PromMatrix( cmap, aa );
00372 *out = trans;
00373
return 0;
00374 }
00376 virtual ~PromMatrix() {
00377
00378 MatDestroy(
mat_);
mat_ = NULL;
00379
if( ghostGID_BID_ != NULL ) {
00380
delete ghostGID_BID_;
delete ghostGID_ndf_;
delete ghostBID_GID_;
00381 }
00382
if( full_mat_ != NULL ) MatDestroy( full_mat_ );
00383
if( varray_ != NULL ) PetscFree( varray_ );
00384
00385 }
00387
virtual int ConvertToSymm();
00388
virtual int ConvertFromSymm();
00389
virtual int ConvertToSuperLU() {
00390
if( isSuperLU() )
return 0;
00391
#if defined(PROM_USE_SUPERLU)
00392
Mat M;
00393
int ierr = MatConvert( mat_, MATSUPERLU_DIST, &M); CHKERRQ(ierr);
00394 MatDestroy(mat_); mat_ = M;
00395
#endif
00396
return 0;
00397 }
00398
virtual bool isSuperLU()const{
00399
return FALSE;
00400 }
00402
int GetLocalNodeRow(
const int brow,
const int len,
int &ncols,
int adjacs[],
00403
double **Aij = NULL )
const ;
00404
private:
00405
int GetNodeScalarRow_PETSc(
const int row,
const int len,
int &ncols,
00406
int Brp[],
double **Bap )
const;
00407
int GetLocal_constBlk_NodeRow(
const int brow,
const int len,
int &ncols,
00408
int adjacs[],
double **Aij = NULL )
const ;
00409
int GetSymmetricLocal_constBlk_NodeRow(
const int brow,
const int len,
int &ncols,
00410
int adjacs[],
double **Aij = NULL )
const ;
00411
int GetLocalVBRNodeRow(
const int brow,
const int len,
int &ncols,
00412
int adjacs[],
double **Aij = NULL )
const ;
00413
public:
00414
int GetDiagonal(
PromVector_base *work )
const {
00415 assert(
this!=NULL && work != NULL);
00416
const PromVector *vec = dynamic_cast<const PromVector*>(work);
00417 assert(vec!=NULL);
00418
return MatGetDiagonal( mat_, vec->
vec_ );
00419 }
00421 virtual int MultTranspose(
const PromVector_base *
const X,
00422
PromVector_base *
const Y )
const {
00423 assert(
this!=NULL);
00424
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00425
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00426
return MatMultTranspose(
mat_, x->
vec_, y->
vec_ );
00427 }
00429 virtual int MultTransposeAdd(
const PromVector_base *
const W,
00430
const PromVector_base *
const X,
00431
PromVector_base *
const Y )
const {
00432
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00433
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00434
const PromVector *w = dynamic_cast<const PromVector*>(W);assert(w!=NULL);
00435
return MatMultTransposeAdd(
mat_, w->
vec_, x->
vec_, y->
vec_ );
00436 }
00438 virtual int Mult(
const PromVector_base *
const X,
00439
PromVector_base *
const Y )
const {
00440 assert(
this!=NULL);
00441
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00442
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00443
return MatMult(
mat_, x->
vec_, y->
vec_ );
00444 }
00446 virtual int KSPMult(
const PromVector_base *
const x,
00447
PromVector_base *
const b )
const {
00448
return Mult(x,b);
00449 }
00451 virtual int MultAdd(
const PromVector_base *
const X,
00452
const PromVector_base *
const Y,
00453
PromVector_base *
const W )
const{
00454 assert(
this!=NULL);
00455
const PromVector *x = dynamic_cast<const PromVector*>(X);assert(x!=NULL);
00456
const PromVector *y = dynamic_cast<const PromVector*>(Y);assert(y!=NULL);
00457
const PromVector *w = dynamic_cast<const PromVector*>(W);assert(w!=NULL);
00458
return MatMultAdd(
mat_, x->
vec_, y->
vec_, w->
vec_ );
00459 }
00460
virtual int GetOwnershipRange(
int *first,
int *end )
const {
00461 assert(
this!=NULL);
00462
int ierr = MatGetOwnershipRange( mat_, first, end );
00463
return ierr;
00464 }
00465
int GetRow(
int row,
int *ncols,
int **colpp=NULL,
double **arrdat=NULL)
const{
00466 assert(
this!=NULL);
00467
if ( colpp == NULL && arrdat == NULL ) {
00468
return MatGetRow( mat_, row, ncols, PETSC_NULL, PETSC_NULL );
00469 }
00470
else if( arrdat == NULL && colpp != NULL ) {
00471
return MatGetRow( mat_, row, ncols, colpp, PETSC_NULL );
00472 }
00473
else if( colpp == NULL && arrdat != NULL ) {
00474
return MatGetRow( mat_, row, ncols, PETSC_NULL, arrdat );
00475 }
00476
else {
00477
return MatGetRow( mat_, row, ncols, colpp, arrdat );
00478 }
00479 }
00480
int RestoreRow(
int row,
int*ncols,
int**colpp=NULL,
double**arrdat=NULL)
const{
00481 assert(
this!=NULL);
00482
return MatRestoreRow( mat_, row, ncols, colpp, arrdat );
00483 }
00484
int SetValues(
const int nrow,
int *pgeqi,
const int ncol,
int *pcol,
00485
double *vals,
const int add_type );
00486
int SetValuesBlocked(
const int nrow,
int *pgidi,
const int ncol,
00487
int *pcol,
double *vals,
const int add_type);
00488
int ZeroRows( PromIS is,
double diag = 0.0 ){
00489 assert(
this!=NULL);
00490 dirty_data_ = TRUE;
00491
return MatZeroRows( mat_, is, diag == 0.0 ? PETSC_NULL : &diag );
00492 }
00493
virtual int ZeroEntries(){
00494 assert(
this!=NULL);
int ierr;
00495
if(
isSymmetricMatrix() ) {
00496 ierr = ConvertFromSymm(); CHKERRQ(ierr);
00497 }
00498
else {
00499 ierr = MatZeroEntries( mat_ ); CHKERRQ(ierr);
00500 }
00501 dirty_data_ = TRUE;
00502
return 0;
00503 }
00504
int Assembly(){
00505 assert(
this!=NULL);
00506
int ierr = MatAssemblyBegin( mat_, MAT_FINAL_ASSEMBLY ); CHKERRQ(ierr);
00507 ierr = MatAssemblyEnd( mat_, MAT_FINAL_ASSEMBLY ); CHKERRQ(ierr);
00508
return 0;
00509 }
00510
int FlushAssembly(){
00511 assert(
this!=NULL);
00512
int ierr = MatAssemblyBegin( mat_, MAT_FLUSH_ASSEMBLY ); CHKERRQ(ierr);
00513
return MatAssemblyEnd( mat_, MAT_FLUSH_ASSEMBLY );
00514 }
00515
int Shift(
double val ){
00516 assert(
this!=NULL);
00517
return MatShift( &val, mat_ );
00518 }
00519
int Scale(
const PromVector_base *
const L,
00520
const PromVector_base *
const R ){
00521 assert(
this!=NULL);
00522
const PromVector *l = dynamic_cast<const PromVector*>(L);
00523
const PromVector *r = dynamic_cast<const PromVector*>(R);
00524
return MatDiagonalScale( mat_, (l != NULL) ? l->
vec_ : NULL,
00525 (r != NULL) ? r->
vec_ : NULL );
00526 }
00527
int Scale(
double val ) {
00528 assert(
this!=NULL);
00529
if( val == 0.0 )
return ZeroEntries();
00530
else return MatScale( &val, mat_ );
00531 }
00532
int NormFrob(
double *
const norm )
const {
00533 assert(
this!=NULL); PetscScalar nn;
00534
int ierr = MatNorm( mat_, NORM_FROBENIUS, &nn ); CHKERRQ(ierr);
00535 *norm = (
double)nn;
00536
return 0;
00537 }
00538
int NormInf(
double *
const norm )
const {
00539 assert(
this!=NULL); PetscScalar nn;
00540
if(
mat_->stash.size == 1 ) {
00541
int ierr = MatNorm( mat_, NORM_INFINITY, &nn ); CHKERRQ(ierr);
00542 }
00543
else {
00544
int ierr = MatNorm( mat_, NORM_FROBENIUS, &nn ); CHKERRQ(ierr);
00545 }
00546 *norm = (
double)nn/sqrt((
double)
mat_->N);
00547
return 0;
00548 }
00550 int AXPY(
double val,
const PromMatrix_base *
const A ) {
00551 assert(
this!=NULL);
00552
const PromMatrix *AA = dynamic_cast<const PromMatrix*>(A);assert(AA!=NULL);
00553
if( AA->
dirty_data_ == FALSE ) {
00554 AA->
dirty_data_ = TRUE;
00555 AA->
SetDRho( 0.0 );
00556 }
00557
return MatAXPY( &val, AA->
mat_,
mat_, SAME_NONZERO_PATTERN );
00558 }
00559
int SetOption(
int opt ) {
00560 assert(
this!=NULL);
00561
return MatSetOption( mat_, (MatOption)opt );
00562 }
00563
virtual int getN()
const {
return mat_->N; }
00564
virtual int getn()
const {
return mat_->n; }
00565
virtual int getM()
const {
return mat_->M; }
00566
virtual int getm()
const {
return mat_->m; }
00567
int getMNodes()const{
return map_.
nglobal(); }
00568
int getLocalNNZ()
const {
00569 MatInfo info;
00570 MatGetInfo( mat_, MAT_LOCAL, &info );
00571
return (
int)(info.nz_used+.05);
00572 }
00573
int getGlobalNNZ()
const {
00574 MatInfo info;
00575 MatGetInfo( mat_, MAT_GLOBAL_SUM, &info );
00576
return (
int)(info.nz_used+.05);
00577 }
00579 MPI_Comm
MPIComm()
const {
return map_.comm_(); }
00581 virtual bool isSymmetricValued()const{
00582 assert(
this != NULL &&
mat_ != NULL);
00583
if(
isSymmetricMatrix() )
return TRUE;
00584
00585 PetscTruth flg;
00586
int ierr = MatIsSymmetric(
mat_, &flg);
00587
return (flg==PETSC_TRUE);
00588 }
00590 virtual bool isSymmetricMatrix()const{
00591 assert(
this != NULL &&
mat_ != NULL);
00592
int ierr, size; MatType type;
00593 MPI_Comm_size(
mat_->comm, &size );
00594 ierr = MatGetType(
mat_, &type); CHKERRQ(ierr);
00595
if(size==1)
return (strcmp(type,
"seqsbaij")==0);
00596
else return (strcmp(type,
"mpisbaij")==0);
00597 }
00599 int GetGArray(
int **garr,
int *nghosts )
const {
00600
int ierr, bs, size, *out = NULL;
00601 MPI_Comm_size(
mat_->comm, &size );
00602
if( size == 1 ) *nghosts = 0;
00603
else {
00604
if(
isSymmetricMatrix() ) {
00605 SETERRQ(-1,
"GetGArray for symmetric matrix not implemented ");
00606
00607
00608
00609
00610 }
00611
else {
00612 ierr = MatGetBlockSize(
mat_, &bs); CHKERRQ(ierr);
00613
if( bs == 1 ) {
00614 Mat_MPIAIJ *aij = (Mat_MPIAIJ*)
mat_->data;
00615 out = aij->garray;
00616 *nghosts = (out==NULL) ? 0 : aij->B->n;
00617 }
00618
else {
00619 Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)
mat_->data;
00620 Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)baij->B->data;
00621 out = baij->garray;
00622 *nghosts = (out==NULL) ? 0 : B->nbs;
00623 }
00624 }
00625 }
00626
if(garr) *garr = out;
00627
return 0;
00628 }
00629
int RestoreGArray(
int **arr )
const {
return 0; }
00630
bool isOK()
const { assert(
this!=NULL);
return (
mat_ != NULL); }
00631
virtual bool isAssembled()const{
00632 assert(
this!=NULL);
return (
mat_ &&
mat_->assembled);
00633 }
00635 int Print(
char *str=NULL, FILE *ifile = stderr )
const{
00636
int rank,idi,idj1,kk,first_row,last_row,ncols,*colpp;
00637 MatGetOwnershipRange(
mat_, &first_row, &last_row);
00638
double *arrdat;
00639 FILE *file;
00640
if(str == NULL ) file = ifile;
00641
else {
00642
char path[128]; MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
00643 sprintf(path,
"%s_%d", str, rank );
00644 file = fopen(path,
"w"); assert(file!=NULL);
00645 }
00646
for( idi = first_row ; idi < last_row ; idi++ ){
00647 MatGetRow(
mat_, idi, &ncols, &colpp, &arrdat );
00648
for ( kk = 0 ; kk < ncols ; kk++ ){
00649
if( arrdat[kk] == 0.0 )
continue;
00650 idj1 = colpp[kk] + 1;
00651 fprintf(file,
"%d %d %.14e\n",idi + 1, idj1, arrdat[kk]);
00652 }
00653 MatRestoreRow(
mat_,idi,&ncols, &colpp,&arrdat);
00654 }
00655
00656 fclose(file);
00657
return 0;
00658 }
00659
00661
protected:
00662 Mat
mat_;
00663 Mat full_mat_;
00664
mutable int *array_;
00665
public:
00666
00667
static int getLidWithLBid(
const int blid,
const int bs,
00668
const int nloc,
const int lid_leq[]);
00669
mutable double *varray_;
00670 PromTable<int> *ghostGID_BID_;
00671 PromTable<int> *ghostGID_ndf_;
00672 PromTable<int> *ghostBID_GID_;
00673
mutable int varr_sz_;
00674
00675 };
00676
00677
#undef __FUNCT__
00678
#define __FUNCT__ "PromPC"
00679
00680
00683 class PromPC :
public PromPC_base
00684 {
00685
friend class PromPCGaussSeidel;
00686
friend class PromMG;
00687
friend class PromPCKKT_ASM;
00688
friend class PromPCKKT_Seg;
00689
friend class PromPCKKT_Shell;
00690
public :
00692 PromPC(
const PromOptions &opt, PromPerfMonitor &perf,
00693
const MPI_Comm comm) :
00694
pc_(NULL), rwork_(NULL), work_(NULL),
00695
PromPC_base(opt,perf) {
00696 PetscFunctionBegin;
00697 PCCreate( comm, &
pc_ );
00698 PetscStackPop;
00699 }
00701 virtual ~PromPC(){
00702
if(
pc_ != NULL ) PCDestroy(
pc_);
00703
if( work_ != NULL ){ VecDestroy(work_); VecDestroy(rwork_); }
00704 }
00706
virtual int SetType( PromPCType type,
const PromVector_base *
const vB );
00708 virtual PromPCType
getType()
const {
00709 assert(
this != NULL ); PetscTruth flag;
00710
00711 PetscTypeCompare((PetscObject)
pc_, PCILU, &flag);
00712
if(flag)
return PROMPCILU;
00713
00714 PetscTypeCompare((PetscObject)pc_, PCLU, &flag);
00715
if(flag)
return PROMPCLU;
00716
00717 PetscTypeCompare((PetscObject)pc_, PCJACOBI, &flag);
00718
if(flag)
return PROMPCJACOBI;
00719
00720 PetscTypeCompare((PetscObject)pc_, PCASM, &flag);
00721
if(flag)
return PROMPCASM;
00722
00723 PetscTypeCompare((PetscObject)pc_, PCNONE, &flag);
00724
if(flag)
return PROMPCNONE;
00725
00726 PetscPrintf(PETSC_COMM_WORLD,
"[?]%s line %d ERROR: bad pc type???\n",
00727 __FILE__,__LINE__);
00728 exit(1);
00729
return PROMPCILU;
00730 }
00731
virtual int SetAbstractOperator_private(
const PromMatrix_base *
const Ab){
00732
const PromMatrix *AA=dynamic_cast<const PromMatrix*>(Ab);assert(AA!=NULL);
00733 assert(pc_->setupcalled != 2);
00734 pc_->pmat = AA->
mat_;
00735 pc_->mat = AA->
mat_; assert(AA->
mat_ != NULL);
00736
return 0;
00737 }
00738
protected:
00740 int SetUp_private(){
00741
#if defined(PROM_TRACE_PC_SETUP)
00742
PetscPrintf(
pc_->comm,
00743
"\t\t[0]PromPC::SetUp_private this=%p setupcalled=%d\n",
00744
this,
pc_->setupcalled);
00745
#endif
00746
assert(
this!=NULL);
int ierr;
00747 ierr = PCSetUp(
pc_ ); CHKERRQ(ierr);
00748 ierr = PCSetUpOnBlocks(
pc_ ); CHKERRQ(ierr);
00749 assert(
pc_->setupcalled == 2);
00750
return 0;
00751 }
00753 virtual int SetOperator_private(
const PromMatrix_base *
const A ){
00754 assert(
this!=NULL);
00755
if(
pc_ == NULL ) SETERRQ(-1,
"pc_ == NULL");
00756
const PromMatrix *AA=dynamic_cast<const PromMatrix*>(A);assert(AA!=NULL);
00757
00758
pc_->mat = AA->
mat_;
00759
pc_->pmat = AA->
mat_;
00760
pc_->flag = SAME_NONZERO_PATTERN;
00761
if(
pc_->setupcalled == 2 )
pc_->setupcalled = 1;
00762
00763
return 0;
00764 }
00766 virtual int SetNewOperator_private(
const PromMatrix_base *
const A ){
00767 assert(
this!=NULL);
00768
if(
pc_ == NULL ) SETERRQ(-1,
"pc_ == NULL");
00769
const PromMatrix *AA=dynamic_cast<const PromMatrix*>(A);assert(AA!=NULL);
00770
00771
pc_->mat = AA->
mat_;
00772
pc_->pmat = AA->
mat_;
00773
pc_->flag = DIFFERENT_NONZERO_PATTERN;
00774
if(
pc_->setupcalled == 2 )
pc_->setupcalled = 1;
00775
00776
return 0;
00777 }
00778
public:
00780
int CreateASM(
const int nblocks, PromIS *blockISs );
00781
00783 virtual const char *
getPCString()
const {
00784 assert(
this!=NULL); assert(
pc_!=NULL);
00785 PetscFunctionBegin;
00786 PCType pctype;
00787 PCGetType(
pc_, &pctype );
00788
if( kkt_ == NULL ){
00789 PetscTruth isasm;
00790 PetscTypeCompare((PetscObject)
pc_,PCASM,&isasm);
00791
if( isasm ){
00792
int nlocal, first; KSP *psles; PC subpc;
00793
int ierr = PCASMGetSubKSP( pc_, &nlocal, &first, &psles );
00794
if(ierr)
return "ERROR-1";
00795 KSPGetPC( psles[0], &subpc ); PCType subpctype;
00796 PCGetType( subpc, &subpctype );
00797 PetscTypeCompare((PetscObject)pc_,PCILU,&isasm);
00798
if(isasm) pctype = subpctype;
00799 }
00800 }
00801 PetscFunctionReturn(pctype);
00802 }
00804 virtual const char *
getSubPCString()
const {
00805 assert(
this!=NULL); assert(
pc_!=NULL);
00806
if( kkt_ != NULL )
return kkt_->getPCString();
00807 PetscTruth isasm; PCType subpctype;
00808 PetscTypeCompare((PetscObject)
pc_,PCASM,&isasm);
00809
if( isasm ){
00810
int nlocal, first; KSP *psles; PC subpc;
00811
int ierr = PCASMGetSubKSP( pc_, &nlocal, &first, &psles );
00812
if(ierr)
return "ERROR-2";
00813 KSPGetPC( psles[0], &subpc );
00814 PCGetType( subpc, &subpctype );
00815
return subpctype;
00816 }
00817
else return PromPCStrings[PROMPCNONE];
00818 }
00820 virtual int getNumBlocks()
const {
00821 assert(
this!=NULL);
00822 PetscFunctionBegin;
00823
if(
pc_ == NULL ) SETERRQ(-1,
"pc_ == NULL");
00824 PetscTruth isasm;
int ierr;
00825 ierr = PetscTypeCompare( (PetscObject)
pc_, PCASM, &isasm ); CHKERRQ(ierr);
00826
if( isasm ) {
00827
int nlocal, first; KSP *psles;
00828 ierr = PCASMGetSubKSP( pc_, &nlocal, &first, &psles ); CHKERRQ(ierr);
00829 PetscFunctionReturn(nlocal);
00830 }
00831
else if( kkt_ != NULL ) PetscFunctionReturn(kkt_->getNumBlocks());
00832 PetscFunctionReturn(0);
00833 }
00835
virtual int Apply_private(
const PromVector_base *
const bbB,
00836
PromVector_base *
const xxB,
const bool zerox=TRUE);
00838
protected:
00839 PC
pc_;
00840 Vec work_;
00841 Vec rwork_;
00842 };
00843
00844
00845
typedef struct {
00846
int n,n_local,n_local_true;
00847
int is_flg;
00848
int overlap;
00849 KSP *ksp;
00850 VecScatter *scat;
00851 Vec *x,*y;
00852 IS *is;
00853 Mat *mat,*pmat;
00854 PCASMType type;
00855
int same_local_solves;
00856
int inplace;
00857
00858
00859 }PETSc_ASM;
00860
00861
class PromGSNode;
00862
int PromDoSchwarzBlocks(Mat AA,
const int nb,
const int blocks[],PETSc_ASM *osm,
00863
const PromVector *
const bb,
PromVector *
const xx,
00864
const int ndf,
const int my0,
00865
const int my0Eq,
const bool havgh,
const bool pre_s,
00866
const PromTable<PromGSNode*> *gid_ghost,
00867
const double ghostx[],
int &numops );
00868
00869
#endif // __PROM_PETSC_H__