Actual source code: esles.c

  1: /*
  2:       Wrappers for PETSc PC ESI implementation
  3: */

 5:  #include esi/petsc/solveriterative.h
 6:  #include esi/petsc/preconditioner.h

  8: esi::petsc::SolverIterative<double,int>::SolverIterative(MPI_Comm icomm)
  9: {
 10:   int      ierr;

 12:   KSPCreate(icomm,&this->ksp);if (ierr) return;
 13:   KSPSetOptionsPrefix(this->ksp,"esi_");
 14:   KSPSetFromOptions(this->ksp);

 16:   PetscObjectGetComm((PetscObject)this->ksp,&this->comm);if (ierr) return;
 17:   this->op = 0;
 18: }

 20: esi::petsc::SolverIterative<double,int>::SolverIterative(KSP iksp)
 21: {
 23:   this->ksp    = iksp;
 24:   PetscObjectGetComm((PetscObject)this->ksp,&this->comm);if (ierr) return;
 25:   PetscObjectReference((PetscObject)iksp);if (ierr) return;
 26: }

 28: esi::petsc::SolverIterative<double,int>::~SolverIterative()
 29: {
 31:   PetscObjectDereference((PetscObject)this->ksp);if (ierr) return;
 32:   if (this->op) {this->op->deleteReference();if (ierr) return;}
 33: }

 35: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getInterface(const char* name, void *& iface)
 36: {
 37:   PetscTruth flg;

 39:   if (!PetscStrcmp(name,"esi::Object",&flg),flg){
 40:     iface = (void *) (esi::Object *) this;
 41:   } else if (!PetscStrcmp(name,"esi::Operator",&flg),flg){
 42:     iface = (void *) (esi::Operator<double,int> *) this;
 43:   } else if (!PetscStrcmp(name,"esi::SolverIterative",&flg),flg){
 44:     iface = (void *) (esi::SolverIterative<double,int> *) this;
 45:   } else if (!PetscStrcmp(name,"esi::Solver",&flg),flg){
 46:     iface = (void *) (esi::Solver<double,int> *) this;
 47:   } else if (!PetscStrcmp(name,"KSP",&flg),flg){
 48:     iface = (void *) this->ksp;
 49:   } else if (!PetscStrcmp(name,"esi::petsc::SolverIterative",&flg),flg){
 50:     iface = (void *) (esi::petsc::SolverIterative<double,int> *) this;
 51:   } else {
 52:     iface = 0;
 53:   }
 54:   return 0;
 55: }

 57: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getInterfacesSupported(esi::Argv * list)
 58: {
 59:   list->appendArg("esi::Object");
 60:   list->appendArg("esi::Operator");
 61:   list->appendArg("esi::SolverIterative");
 62:   list->appendArg("esi::Solver");
 63:   list->appendArg("esi::petsc::SolverIterative");
 64:   list->appendArg("KSP");
 65:   return 0;
 66: }

 68: esi::ErrorCode esi::petsc::SolverIterative<double,int>::apply( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
 69: {
 71:   Vec py,px;

 73:   yy.getInterface("Vec",reinterpret_cast<void*&>(py));if (ierr) return ierr;
 74:   xx.getInterface("Vec",reinterpret_cast<void*&>(px));if (ierr) return ierr;

 76:   KSPSetRhs(this->ksp,px);
 77:   KSPSetSolution(this->ksp,py);
 78:   return KSPSolve(this->ksp);
 79: }

 81: esi::ErrorCode esi::petsc::SolverIterative<double,int>::solve( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
 82: {
 83:   return this->apply(xx,yy);
 84: }

 86: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setup()
 87: {
 88:   return 0;
 89: }

 91: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setOperator( esi::Operator<double,int> &iop)
 92: {
 93:   /*
 94:         For now require Operator to be a PETSc Mat
 95:   */
 96:   Mat A;
 97:   this->op = &iop;
 98:   iop.addReference();
 99:   int iop.getInterface("Mat",reinterpret_cast<void*&>(A));
100:   if (!A) {
101:     /* MatCreate( &A);if (ierr) return ierr;
102:        MatSetType(A,MATESI);if (ierr) return ierr;
103:        MatESISetOperator(A,&op);if (ierr) return ierr;*/
104:   }
105:   KSPSetOperators(this->ksp,A,A,DIFFERENT_NONZERO_PATTERN);
106:   return 0;
107: }

109: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getOperator( esi::Operator<double,int> *&iop)
110: {
111:   iop = this->op;
112:   return 0;
113: }

115: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getPreconditioner( esi::Preconditioner<double,int> *&ipre)
116: {
117:   if (!this->pre) {
118:     PC  pc;
119:     int KSPGetPC(this->ksp,&pc);if (ierr) return ierr;
120:     this->pre = new ::esi::petsc::Preconditioner<double,int>(pc);
121:   }
122:   ipre = this->pre;
123:   return 0;
124: }

126: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setPreconditioner( esi::Preconditioner<double,int> &ipre)
127: {
128:   PC  pc;
129:   int KSPGetPC(this->ksp,&pc);if (ierr) return ierr;
130:       PCSetType(pc,PCESI);if (ierr) return ierr;
131:       PCESISetPreconditioner(pc,&ipre);if (ierr) return ierr;
132:   if (this->pre) {this->pre->deleteReference();if (ierr) return ierr;}
133:   this->pre = &ipre;
134:   ipre.addReference();
135:   return 0;
136: }

138: esi::ErrorCode esi::petsc::SolverIterative<double,int>::parameters(int numParams, char** paramStrings)
139: {
140:   return 1;
141: }

143: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getTolerance( magnitude_type & tol )
144: {
146:   KSPGetTolerances(this->ksp,&tol,0,0,0);if (ierr) return ierr;
147:   return 0;
148: }

150: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setTolerance( magnitude_type  tol )
151: {
153:   KSPSetTolerances(this->ksp,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);if (ierr) return ierr;
154:   return 0;
155: }

157: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setMaxIterations(int its)
158: {
160:   KSPSetTolerances(this->ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,its);if (ierr) return ierr;
161:   return 0;
162: }

164: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getMaxIterations(int &its)
165: {
167:   KSPGetTolerances(this->ksp,0,0,0,&its);if (ierr) return ierr;
168:   return 0;
169: }

171: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getNumIterationsTaken(int &its)
172: {
174:   KSPGetIterationNumber(this->ksp,&its);if (ierr) return ierr;
175:   return 0;
176: }

178: // --------------------------------------------------------------------------
179: ::esi::ErrorCode esi::petsc::SolverIterative<double,int>::Factory::create (char *commname,void *icomm,::esi::SolverIterative<double,int>*&v)
180: {
181:   PetscTruth flg;
182:   int        PetscStrcmp(commname,"MPI",&flg);
183:   v = new esi::petsc::SolverIterative<double,int>(*(MPI_Comm*)icomm);
184:   return 0;
185: };

187: //::esi::petsc::SolverIterativeFactory<double,int> SFInstForIntel64CompilerBug;

189: EXTERN_C_BEGIN
190: ::esi::SolverIterative<double,int>::Factory *create_esi_petsc_solveriterativefactory(void)
191: {
192:   return dynamic_cast< ::esi::SolverIterative<double,int>::Factory *>(new esi::petsc::SolverIterative<double,int>::Factory);
193: }
194: EXTERN_C_END