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->pobject = (PetscObject)this->vec;
 25:   this->map = (::esi::IndexSpace<int> *)inmap;
 26:   this->map->addReference();
 27:   PetscObjectGetComm((PetscObject)this->vec,&this->comm);if (ierr) return;
 28: }

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

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

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

 52: /* ---------------esi::Object methods ------------------------------------------------------------ */

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


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

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

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

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

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

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

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

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

127:   return VecCopy(y->vec,this->vec);
128: }

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

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

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

151:   return VecPointwiseMult(y->vec,this->vec,this->vec);
152: }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

246: // --------------------------------------------------------------------------------------------------------
247: namespace esi{namespace petsc{
248:   template<class Scalar,class Ordinal> class VectorFactory : public virtual ::esi::VectorFactory<Scalar,Ordinal>
249: {
250:   public:

252:     // constructor
253:     VectorFactory(void){};
254: 
255:     // Destructor.
256:     virtual ~VectorFactory(void){};

258:     // Interface for gov::cca::Component
259: #if defined(PETSC_HAVE_CCA)
260:     virtual void setServices(gov::cca::Services *svc)
261:     {
262:       svc->addProvidesPort(this,svc->createPortInfo("getVector", "esi::VectorFactory", 0));
263:     };
264: #endif

266:     // Construct a Vector
267:     virtual ::esi::ErrorCode getVector(::esi::IndexSpace<Ordinal>&map,::esi::Vector<Scalar,Ordinal>*&v)
268:     {
269:       v = new esi::petsc::Vector<Scalar,Ordinal>(&map);
270:       return 0;
271:     };
272: };
273: }}

275: ::esi::petsc::VectorFactory<double,int> VFInstForIntel64CompilerBug;

277: EXTERN_C_BEGIN
278: #if defined(PETSC_HAVE_CCA)
279: gov::cca::Component *create_esi_petsc_vectorfactory(void)
280: {
281:   return dynamic_cast<gov::cca::Component *>(new esi::petsc::VectorFactory<double,int>);
282: }
283: #else
284: ::esi::VectorFactory<double,int> *create_esi_petsc_vectorfactory(void)
285: {
286:   return dynamic_cast< ::esi::VectorFactory<double,int> *>(new esi::petsc::VectorFactory<double,int>);
287: }
288: #endif
289: EXTERN_C_END

291: // --------------------------------------------------------------------------------------------------------
292: #if defined(PETSC_HAVE_TRILINOS)
293: #define PETRA_MPI /* used by Ptera to indicate MPI code */
294: #include "Petra_ESI_Vector.h"

296: template<class Scalar,class Ordinal> class Petra_ESI_VectorFactory : public virtual ::esi::VectorFactory<Scalar,Ordinal>
297: {
298:   public:

300:     // constructor
301:     Petra_ESI_VectorFactory(void) {};
302: 
303:     // Destructor.
304:     virtual ~Petra_ESI_VectorFactory(void) {};

306:     // Interface for gov::cca::Component
307: #if defined(PETSC_HAVE_CCA)
308:     virtual void setServices(gov::cca::Services *svc)
309:     {
310:       svc->addProvidesPort(this,svc->createPortInfo("getVector", "esi::VectorFactory", 0));
311:     };
312: #endif

314:     // Construct a Vector
315:     virtual ::esi::ErrorCode getVector(::esi::IndexSpace<Ordinal>&lmap,::esi::Vector<Scalar,Ordinal>*&v)
316:     {
317:       Petra_ESI_IndexSpace<Ordinal> *map;
318:       int lmap.getInterface("Petra_ESI_IndexSpace",reinterpret_cast<void *&>(map));
319:       if (!map) SETERRQ(1,"Requires Petra_ESI_IndexSpace");
320:       v = new Petra_ESI_Vector<Scalar,Ordinal>(*map);
321:       //      map->addReference();  /* Petra has bug and does not increase reference count */
322:       if (!v) SETERRQ(1,"Unable to create new Petra_ESI_Vector");
323:       return 0;
324:     };
325: };

327: EXTERN_C_BEGIN
328: #if defined(PETSC_HAVE_CCA)
329: gov::cca::Component *create_petra_esi_vectorfactory(void)
330: {
331:   return dynamic_cast<gov::cca::Component *>(new Petra_ESI_VectorFactory<double,int>);
332: }
333: #else
334: ::esi::VectorFactory<double,int> *create_petra_esi_vectorfactory(void)
335: {
336:   return dynamic_cast< ::esi::VectorFactory<double,int> *>(new Petra_ESI_VectorFactory<double,int>);
337: }
338: #endif
339: EXTERN_C_END
340: #endif

342: // --------------------------------------------------------------------------------------------------------

344: // CCAFFEINE expects each .so file to have a getComponentList function.
345: // See dccafe/cxx/dc/framework/ComponentFactory.h for details.
346: EXTERN_C_BEGIN
347: char **getComponentList() {
348:   static char *list[7];
349:   list[0] = "create_esi_petsc_vectorfactory esi::petsc::Vector";
350:   list[1] = "create_petra_esi_vectorfactory Petra_ESI_Vector";
351:   list[2] = "create_esi_petsc_indexspacefactory esi::petsc::IndexSpace";
352:   list[3] = "create_petra_esi_indexspacefactory Petra_ESI_IndexSpace";
353:   list[4] = "create_esi_petsc_operatorfactory esi::petsc::Operator";
354:   list[5] = "create_petra_esi_operatorfactory Petra_ESI_CRS_Matrix";
355:   list[6] = 0;
356:   return list;
357: }
358: EXTERN_C_END