Actual source code: evector.c



  4: /*
  5:    Makes a PETSc vector look like a ESI
  6: */

 8:  #include esi/petsc/vector.h

 10: esi::petsc::Vector<double,int>::Vector( ::esi::IndexSpace<int> *inmap)
 11: {
 12:   ::esi::ErrorCode  ierr;
 13:   int               n,N;
 14:   MPI_Comm          *icomm;

 16:   inmap->getRunTimeModel("MPI",reinterpret_cast<void *&>(icomm));if (ierr) return;

 18:   inmap->getLocalSize(n);if (ierr) return;
 19:   inmap->getGlobalSize(N);if (ierr) return;
 20:   VecCreate(*icomm,&this->vec);if (ierr) return;
 21:   VecSetSizes(this->vec,n,N);if (ierr) return;
 22:   PetscObjectSetOptionsPrefix((PetscObject)this->vec,"esi_");if (ierr) return;
 23:   VecSetFromOptions(this->vec);if (ierr) return;
 24:   this->map = (::esi::IndexSpace<int> *)inmap;
 25:   this->map->addReference();
 26:   PetscObjectGetComm((PetscObject)this->vec,&this->comm);if (ierr) return;
 27: }

 29: esi::petsc::Vector<double,int>::Vector( Vec pvec)
 30: {
 31:   ::esi::ErrorCode  ierr;
 32:   int               n,N;
 33: 
 34:   this->vec     = pvec;
 35:   PetscObjectReference((PetscObject)pvec);if (ierr) return;
 36:   PetscObjectGetComm((PetscObject)this->vec,&this->comm);if (ierr) return;

 38:   VecGetSize(pvec,&N);if (ierr) return;
 39:   VecGetLocalSize(pvec,&n);if (ierr) return;
 40:   this->map = new esi::petsc::IndexSpace<int>(this->comm,n,N);
 41: }

 43: esi::petsc::Vector<double,int>::~Vector()
 44: {
 46:   this->map->deleteReference();if (ierr) return;
 47:   VecDestroy(this->vec);if (ierr) return;
 48: }

 50: /* ---------------esi::Object methods ------------------------------------------------------------ */

 52: ::esi::ErrorCode esi::petsc::Vector<double,int>::getInterface(const char* name, void *& iface)
 53: {
 54:   PetscTruth flg;
 55:   if (PetscStrcmp(name,"esi::Object",&flg),flg){
 56:     iface = (void *) (::esi::Object *) this;
 57:   } else if (PetscStrcmp(name,"esi::Vector",&flg),flg){
 58:     iface = (void *) (::esi::Vector<double,int> *) this;
 59:   } else if (PetscStrcmp(name,"esi::petsc::Vector",&flg),flg){
 60:     iface = (void *) (::esi::petsc::Vector<double,int> *) this;
 61:   } else if (PetscStrcmp(name,"esi::VectorReplaceAccess",&flg),flg){
 62:     iface = (void *) (::esi::VectorReplaceAccess<double,int> *) this;
 63:   } else if (PetscStrcmp(name,"Vec",&flg),flg){
 64:     iface = (void *) this->vec;
 65:   } else {
 66:     iface = 0;
 67:   }
 68:   return 0;
 69: }


 72: ::esi::ErrorCode esi::petsc::Vector<double,int>::getInterfacesSupported(::esi::Argv * list)
 73: {
 74:   list->appendArg("esi::Object");
 75:   list->appendArg("esi::Vector");
 76:   list->appendArg("esi::VectorReplaceAccess");
 77:   list->appendArg("esi::petsc::Vector");
 78:   list->appendArg("Vec");
 79:   return 0;
 80: }

 82: /*
 83:     Note: this returns the map used in creating the vector;
 84:   it is not the same as the PETSc map contained inside the PETSc vector
 85: */
 86: ::esi::ErrorCode esi::petsc::Vector<double,int>::getIndexSpace( ::esi::IndexSpace<int>*& outmap)
 87: {
 88:   outmap = this->map;
 89:   return 0;
 90: }

 92: ::esi::ErrorCode esi::petsc::Vector<double,int>::getGlobalSize( int & dim)
 93: {
 94:   return VecGetSize(this->vec,&dim);
 95: }

 97: ::esi::ErrorCode esi::petsc::Vector<double,int>::getLocalSize( int & dim)
 98: {
 99:   return VecGetLocalSize(this->vec,&dim);
100: }

102: ::esi::ErrorCode esi::petsc::Vector<double,int>::clone( ::esi::Vector<double,int>*& outvector)
103: {
104:   int                    ierr;
105:   ::esi::IndexSpace<int> *lmap;
106:   ::esi::IndexSpace<int> *amap;

108:   this->getIndexSpace(lmap);
109:   lmap->getInterface("esi::IndexSpace",reinterpret_cast<void *&>(amap));
110:   outvector = (::esi::Vector<double,int> *) new esi::petsc::Vector<double,int>(amap);
111:   return 0;
112: }

114: /*
115:   Currently only works if both vectors are PETSc 
116: */
117: ::esi::ErrorCode esi::petsc::Vector<double,int>::copy( ::esi::Vector<double,int> &yy)
118: {
119:   esi::petsc::Vector<double,int> *y = 0;
120:   int                            ierr;

122:   yy.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
123:   if (!y) return 1;

125:   return VecCopy(y->vec,this->vec);
126: }

128: ::esi::ErrorCode esi::petsc::Vector<double,int>::put( double scalar)
129: {
130:   return VecSet(&scalar,this->vec);
131: }

133: ::esi::ErrorCode esi::petsc::Vector<double,int>::scale( double scalar)
134: {
135:   return VecScale(&scalar,this->vec);
136: }

138: /*
139:   Currently only works if both vectors are PETSc 
140: */
141: ::esi::ErrorCode esi::petsc::Vector<double,int>::scaleDiagonal( ::esi::Vector<double,int> &yy)
142: {
143:   ::esi::ErrorCode                 ierr;
144:   esi::petsc::Vector<double,int> *y;
145: 
146:   yy.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
147:   if (!y) return 1;

149:   return VecPointwiseMult(y->vec,this->vec,this->vec);
150: }

152: ::esi::ErrorCode esi::petsc::Vector<double,int>::norm1(magnitude_type &scalar)
153: {
154:   return VecNorm(this->vec,NORM_1,&scalar);
155: }

157: ::esi::ErrorCode esi::petsc::Vector<double,int>::norm2(magnitude_type &scalar)
158: {
159:   return VecNorm(this->vec,NORM_2,&scalar);
160: }

162: ::esi::ErrorCode esi::petsc::Vector<double,int>::norm2squared(magnitude_type &scalar)
163: {
164:   int VecNorm(this->vec,NORM_2,&scalar);
165:   scalar *= scalar;
166:   return 0;
167: }

169: ::esi::ErrorCode esi::petsc::Vector<double,int>::normInfinity(magnitude_type &scalar)
170: {
171:   return VecNorm(this->vec,NORM_INFINITY,&scalar);
172: }

174: /*
175:   Currently only works if both vectors are PETSc 
176: */
177: ::esi::ErrorCode esi::petsc::Vector<double,int>::dot( ::esi::Vector<double,int> &yy,double &product)
178: {

181:   esi::petsc::Vector<double,int> *y;  yy.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
182:   if (!y) return 1;
183:   return  VecDot(this->vec,y->vec,&product);
184: }

186: /*
187:   Currently only works if both vectors are PETSc 
188: */
189: ::esi::ErrorCode esi::petsc::Vector<double,int>::axpy(  ::esi::Vector<double,int> &yy,double scalar)
190: {

193:   esi::petsc::Vector<double,int> *y;  yy.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
194:   if (!y) return 1;
195:   return VecAXPY(&scalar,y->vec,this->vec);
196: }

198: ::esi::ErrorCode esi::petsc::Vector<double,int>::axpby(double dy1,  ::esi::Vector<double,int> &yy1,double y2,  ::esi::Vector<double,int> &yy2)
199: {

202:   esi::petsc::Vector<double,int> *y;  yy1.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
203:   if (!y) return 1;
204:   esi::petsc::Vector<double,int> *w;  yy2.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(w));
205:   if (!w) return 1;
206:   VecCopy(y->vec,this->vec);
207:   VecScale(&dy1,this->vec);
208:   VecAXPY(&y2,w->vec,this->vec);
209:   return(0);
210: }

212: /*
213:   Currently only works if both vectors are PETSc 
214: */
215: ::esi::ErrorCode esi::petsc::Vector<double,int>::aypx(double scalar,  ::esi::Vector<double,int> &yy)
216: {
218: 
219:   esi::petsc::Vector<double,int> *y;  yy.getInterface("esi::petsc::Vector",reinterpret_cast<void *&>(y));
220:   if (!y) return 1;
221:   return VecAYPX(&scalar,y->vec,this->vec);
222: }

224: ::esi::ErrorCode esi::petsc::Vector<double,int>::getCoefPtrReadLock(double *&pointer)
225: {
226:   return VecGetArray(this->vec,&pointer);
227: }

229: ::esi::ErrorCode esi::petsc::Vector<double,int>::getCoefPtrReadWriteLock(double *&pointer)
230: {
231:   return VecGetArray(this->vec,&pointer);
232: }

234: ::esi::ErrorCode esi::petsc::Vector<double,int>::releaseCoefPtrLock(double *&pointer)
235: {
236:   return VecRestoreArray(this->vec,&pointer);
237: }

239: ::esi::ErrorCode esi::petsc::Vector<double,int>::setArrayPointer(double *pointer,int length)
240: {
241:   return VecPlaceArray(this->vec,pointer);
242: }

244: ::esi::ErrorCode esi::petsc::Vector<double,int>::Factory::create(::esi::IndexSpace<int>&imap,::esi::Vector<double,int>*&v)
245: {
246:   v = new esi::petsc::Vector<double,int>(&imap);
247:   return 0;
248: };

250: /* ::esi::petsc::VectorFactory<double,int> VFInstForIntel64CompilerBug; */

252: EXTERN_C_BEGIN
253: ::esi::Vector<double,int>::Factory *create_esi_petsc_vectorfactory(void)
254: {
255:   return dynamic_cast< ::esi::Vector<double,int>::Factory *>(new esi::petsc::Vector<double,int>::Factory);
256: }
257: EXTERN_C_END

259: // --------------------------------------------------------------------------------------------------------
260: #if defined(PETSC_HAVE_TRILINOS)
261: #define PETRA_MPI /* used by Ptera to indicate MPI code */
262: #include "Petra_ESI_Vector.h"

264: template<class Scalar,class Ordinal> class Petra_ESI_VectorFactory : public virtual ::esi::VectorFactory<Scalar,Ordinal>
265: {
266:   public:

268:     // constructor
269:     Petra_ESI_VectorFactory(void) {};
270: 
271:     // Destructor.
272:     virtual ~Petra_ESI_VectorFactory(void) {};

274:     // Construct a Vector
275:     virtual ::esi::ErrorCode getVector(::esi::IndexSpace<Ordinal>&lmap,::esi::Vector<Scalar,Ordinal>*&v)
276:     {
277:       Petra_ESI_IndexSpace<Ordinal> *map;
278:       int lmap.getInterface("Petra_ESI_IndexSpace",reinterpret_cast<void *&>(map));
279:       if (!map) SETERRQ(1,"Requires Petra_ESI_IndexSpace");
280:       v = new Petra_ESI_Vector<Scalar,Ordinal>(*map);
281:       //      map->addReference();  /* Petra has bug and does not increase reference count */
282:       if (!v) SETERRQ(1,"Unable to create new Petra_ESI_Vector");
283:       return 0;
284:     };
285: };

287: EXTERN_C_BEGIN
288: ::esi::VectorFactory<double,int> *create_petra_esi_vectorfactory(void)
289: {
290:   return dynamic_cast< ::esi::VectorFactory<double,int> *>(new Petra_ESI_VectorFactory<double,int>);
291: }
292: EXTERN_C_END
293: #endif