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:   SLESCreate(icomm,&this->sles);if (ierr) return;
 13:   SLESSetOptionsPrefix(this->sles,"esi_");
 14:   SLESSetFromOptions(this->sles);

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

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

 28: esi::petsc::SolverIterative<double,int>::~SolverIterative()
 29: {
 31:   PetscObjectDereference((PetscObject)this->sles);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,"SLES",&flg),flg){
 48:     iface = (void *) this->sles;
 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("SLES");
 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:   return SLESSolve(this->sles,px,py,PETSC_NULL);
 77: }

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

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

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

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

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

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

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

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

151: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setTolerance( magnitude_type  tol )
152: {
154:   KSP ksp;
155:   SLESGetKSP(this->sles,&ksp);if (ierr) return ierr;
156:   KSPSetTolerances(ksp,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);if (ierr) return ierr;
157:   return 0;
158: }

160: esi::ErrorCode esi::petsc::SolverIterative<double,int>::setMaxIterations(int its)
161: {
163:   KSP ksp;
164:   SLESGetKSP(this->sles,&ksp);if (ierr) return ierr;
165:   KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,its);if (ierr) return ierr;
166:   return 0;
167: }

169: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getMaxIterations(int &its)
170: {
172:   KSP ksp;
173:   SLESGetKSP(this->sles,&ksp);if (ierr) return ierr;
174:   KSPGetTolerances(ksp,0,0,0,&its);if (ierr) return ierr;
175:   return 0;
176: }

178: esi::ErrorCode esi::petsc::SolverIterative<double,int>::getNumIterationsTaken(int &its)
179: {
181:   KSP ksp;
182:   SLESGetKSP(this->sles,&ksp);if (ierr) return ierr;
183:   KSPGetIterationNumber(ksp,&its);if (ierr) return ierr;
184:   return 0;
185: }

187: // --------------------------------------------------------------------------
188: ::esi::ErrorCode esi::petsc::SolverIterative<double,int>::Factory::create (char *commname,void *icomm,::esi::SolverIterative<double,int>*&v)
189: {
190:   PetscTruth flg;
191:   int        PetscStrcmp(commname,"MPI",&flg);
192:   v = new esi::petsc::SolverIterative<double,int>(*(MPI_Comm*)icomm);
193:   return 0;
194: };

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

198: EXTERN_C_BEGIN
199: ::esi::SolverIterative<double,int>::Factory *create_esi_petsc_solveriterativefactory(void)
200: {
201:   return dynamic_cast< ::esi::SolverIterative<double,int>::Factory *>(new esi::petsc::SolverIterative<double,int>::Factory);
202: }
203: EXTERN_C_END