Main Page | Class Hierarchy | Class List | File List | Class Members

prom_petsc.hh

00001 // $Id: prom_petsc.hh,v 1.34 2004/05/07 20:55:04 adams Exp $ 00002 // Author: Mark F. Adams 00003 // Copyright (c) 2000 by Mark F. Adams 00004 // Filename: prom_petsc.hh 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 //#include "src/ksp/kspimpl.h" 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 ) // hack for VBR 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 // determine if constant ndf 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; // broke 00096 else s2 = tt; // high / low 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); // this will fail while VBR hack is not fixed 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; /* since function returns void cannot use PetscFunctionReturn(); */ 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; /* since function returns void cannot use PetscFunctionReturn(); */ 00192 } 00194 virtual ~PromVector(){ 00195 //if( malled_ ) 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); // todo! 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), //malled_(TRUE), 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); // not used 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 //if(malled_) { 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; // indefinite_ = FALSE; DRhoA_ = -2.0; -- do for coarse grids w/ helpmholtz! 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 ); // this is collective so set here 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 //else return FALSE; // diabled 00585 PetscTruth flg; 00586 int ierr = MatIsSymmetric(mat_, &flg); // not implemented for BAIJ!!! 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 //Mat_MPISBAIJ *baij = (Mat_MPISBAIJ*)mat_->data; // upper left matix 00607 //Mat_SeqSBAIJ *B = (Mat_SeqSBAIJ*)baij->B->data; 00608 //out = baij->garray; 00609 //*nghosts = (out==NULL) ? 0 : B->nbs; 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 { // blocked matrix 00619 Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat_->data; // upper left matix 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 //fprintf( file,"%d %d %.14e\n",last_row, last_row, 0.0 ); 00656 fclose(file); 00657 return 0; 00658 } 00659 00661 protected: 00662 Mat mat_; 00663 Mat full_mat_; 00664 mutable int *array_; 00665 public: 00666 // vbr 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 //const bool malled_; 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 // need to translate 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); // should be called before setup! 00734 pc_->pmat = AA->mat_; // hard set of matrix 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; // new data, refactor 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 // ierr = PCSetOperators( pc_, AA->mat_, AA->mat_, SAME_NONZERO_PATTERN ); 00758 pc_->mat = AA->mat_; // petsc does a crazy reset in PCSetOperators 00759 pc_->pmat = AA->mat_; 00760 pc_->flag = SAME_NONZERO_PATTERN; 00761 if( pc_->setupcalled == 2 ) pc_->setupcalled = 1; // ** soft reset 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 // ierr = PCSetOperators( pc_, AA->mat_, AA->mat_, SAME_NONZERO_PATTERN ); 00771 pc_->mat = AA->mat_; // petsc does a crazy reset in PCSetOperators 00772 pc_->pmat = AA->mat_; 00773 pc_->flag = DIFFERENT_NONZERO_PATTERN; 00774 if( pc_->setupcalled == 2 ) pc_->setupcalled = 1; // ** soft reset 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 }; // PromPC 00843 00844 // want access to PETSc's block data -- hack of all hacks!!! 00845 typedef struct { 00846 int n,n_local,n_local_true; 00847 int is_flg; /* flg set to 1 if the IS created in pcsetup */ 00848 int overlap; /* overlap requested by user */ 00849 KSP *ksp; /* linear solvers for each block */ 00850 VecScatter *scat; /* mapping to subregion */ 00851 Vec *x,*y; 00852 IS *is; /* index set that defines each subdomain */ 00853 Mat *mat,*pmat; /* mat is not currently used */ 00854 PCASMType type; /* use reduced interpolation, restriction or both */ 00855 int same_local_solves; /* flag indicating whether all local solvers are same */ 00856 int inplace; /* indicates that the sub-matrices are deleted after 00857 PCSetUpOnBlocks() is done. Similar to inplace 00858 1 factor_ization in the case of LU and ILU */ 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__

Generated on Fri May 21 14:17:54 2004 by doxygen 1.3.7