Actual source code: epreconditioner.c

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

 5:  #include esi/petsc/preconditioner.h

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

 11:   PCCreate(icomm,&this->pc);if (ierr) return;
 12:   PetscObjectSetOptionsPrefix((PetscObject)this->pc,"esi_");
 13:   PCSetFromOptions(this->pc);

 15:   PetscObjectGetComm((PetscObject)this->pc,&this->comm);if (ierr) return;
 16: }

 18: esi::petsc::Preconditioner<double,int>::Preconditioner(PC ipc)
 19: {
 21:   this->pc      = ipc;
 22:   PetscObjectGetComm((PetscObject)this->pc,&this->comm);if (ierr) return;
 23:   PetscObjectReference((PetscObject)ipc);if (ierr) return;
 24: }

 26: esi::petsc::Preconditioner<double,int>::~Preconditioner()
 27: {
 29:   PetscObjectDereference((PetscObject)this->pc);if (ierr) return;
 30: }

 32: esi::ErrorCode esi::petsc::Preconditioner<double,int>::getInterface(const char* name, void *& iface)
 33: {
 34:   PetscTruth flg;

 36:   if (!PetscStrcmp(name,"esi::Object",&flg),flg){
 37:     iface = (void *) (esi::Object *) this;
 38:   } else if (!PetscStrcmp(name,"esi::Operator",&flg),flg){
 39:     iface = (void *) (esi::Operator<double,int> *) this;
 40:   } else if (!PetscStrcmp(name,"esi::Preconditioner",&flg),flg){
 41:     iface = (void *) (esi::Preconditioner<double,int> *) this;
 42:   } else if (!PetscStrcmp(name,"esi::Solver",&flg),flg){
 43:     iface = (void *) (esi::Solver<double,int> *) this;
 44:   } else if (!PetscStrcmp(name,"PC",&flg),flg){
 45:     iface = (void *) this->pc;
 46:   } else if (!PetscStrcmp(name,"esi::petsc::Preconditioner",&flg),flg){
 47:     iface = (void *) (esi::petsc::Preconditioner<double,int> *) this;
 48:   } else {
 49:     iface = 0;
 50:   }
 51:   return 0;
 52: }

 54: esi::ErrorCode esi::petsc::Preconditioner<double,int>::getInterfacesSupported(esi::Argv * list)
 55: {
 56:   list->appendArg("esi::Object");
 57:   list->appendArg("esi::Operator");
 58:   list->appendArg("esi::Preconditioner");
 59:   list->appendArg("esi::Solver");
 60:   list->appendArg("esi::petsc::Preconditioner");
 61:   list->appendArg("PC");
 62:   return 0;
 63: }


 66: esi::ErrorCode esi::petsc::Preconditioner<double,int>::apply( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
 67: {
 69:   Vec py,px;

 71:   yy.getInterface("Vec",reinterpret_cast<void*&>(py));
 72:   xx.getInterface("Vec",reinterpret_cast<void*&>(px));

 74:   PCSetVector(this->pc,px);
 75:   return PCApply(this->pc,px,py,PC_LEFT);
 76: }

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

 83: esi::ErrorCode esi::petsc::Preconditioner<double,int>::solveLeft( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
 84: {
 86:   Vec py,px;

 88:   yy.getInterface("Vec",reinterpret_cast<void*&>(py));
 89:   xx.getInterface("Vec",reinterpret_cast<void*&>(px));

 91:   return PCApplySymmetricLeft(this->pc,px,py);
 92: }

 94: esi::ErrorCode esi::petsc::Preconditioner<double,int>::solveRight( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
 95: {
 97:   Vec py,px;

 99:   yy.getInterface("Vec",reinterpret_cast<void*&>(py));
100:   xx.getInterface("Vec",reinterpret_cast<void*&>(px));

102:   return PCApplySymmetricRight(this->pc,px,py);
103: }

105: esi::ErrorCode esi::petsc::Preconditioner<double,int>::applyB( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
106: {
107:   int    ierr;
108:   Vec    py,px,work;
109:   PCSide iside= PC_LEFT;

111:   yy.getInterface("Vec",reinterpret_cast<void*&>(py));
112:   xx.getInterface("Vec",reinterpret_cast<void*&>(px));
113:   VecDuplicate(py,&work);
114:   if (this->side == esi::PRECONDITIONER_LEFT)      iside = PC_LEFT;
115:   if (this->side == esi::PRECONDITIONER_RIGHT)     iside = PC_RIGHT;
116:   if (this->side == esi::PRECONDITIONER_TWO_SIDED) iside = PC_SYMMETRIC;
117:   PCApplyBAorAB(this->pc,iside,px,py,work);
118:   VecDestroy(work);
119:   return 0;
120: }

122: esi::ErrorCode esi::petsc::Preconditioner<double,int>::setup()
123: {
124:   return 0;
125: }

127: esi::ErrorCode esi::petsc::Preconditioner<double,int>::setPreconditionerSide(esi::PreconditionerSide iside)
128: {
129:   this->side = iside;
130:   return 0;
131: }

133: esi::ErrorCode esi::petsc::Preconditioner<double,int>::getPreconditionerSide(esi::PreconditionerSide & iside)
134: {
135:   iside = this->side;
136:   return 0;
137: }

139: esi::ErrorCode esi::petsc::Preconditioner<double,int>::setOperator( esi::Operator<double,int> &op)
140: {
141:   /*
142:         For now require Operator to be a PETSc Mat
143:   */
144:   Mat A;
145:   int op.getInterface("Mat",reinterpret_cast<void*&>(A));
146:   PCSetOperators(this->pc,A,A,DIFFERENT_NONZERO_PATTERN);
147:   return 0;
148: }

150: ::esi::ErrorCode esi::petsc::Preconditioner<double,int>::Factory::create(char *commname,void *icomm,::esi::Preconditioner<double,int>*&v)
151: {
152:    PetscTruth flg;
153:    int        PetscStrcmp(commname,"MPI",&flg);
154:    if (!flg) SETERRQ1(1,"Does not support %s, only supports MPI",commname);
155:    v = new esi::petsc::Preconditioner<double,int>(*(MPI_Comm*)icomm);
156:    return 0;
157: };

159: /* ::esi::petsc::PreconditionerFactory<double,int> PFInstForIntel64CompilerBug; */

161: EXTERN_C_BEGIN
162: ::esi::Preconditioner<double,int>::Factory *create_esi_petsc_preconditionerfactory(void)
163: {
164:   return dynamic_cast< ::esi::Preconditioner<double,int>::Factory *>(new esi::petsc::Preconditioner<double,int>::Factory);
165: }
166: EXTERN_C_END