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