Actual source code: ematrix.c
1: /*
2: Wrappers for esi::petsc::Matrix ESI implementation
3: */
5: #include esi/petsc/matrix.h
7: esi::petsc::Matrix<double,int>::Matrix(esi::IndexSpace<int> *inrmap,esi::IndexSpace<int> *incmap)
8: {
9: int ierr,rn,rN,cn,cN;
10: MPI_Comm *icomm;
12: inrmap->getRunTimeModel("MPI",reinterpret_cast<void *&>(icomm));
13: inrmap->getLocalSize(rn);
14: inrmap->getGlobalSize(rN);
15: incmap->getLocalSize(cn);
16: incmap->getGlobalSize(cN);
17: MatCreate(*icomm,rn,cn,rN,cN,&this->mat);if (ierr) return;
18: PetscObjectSetOptionsPrefix((PetscObject)this->mat,"esi");
19: MatSetFromOptions(this->mat);
21: this->rmap = inrmap;
22: this->cmap = incmap;
23: inrmap->addReference();
24: incmap->addReference();
26: this->pobject = (PetscObject)this->mat;
27: PetscObjectGetComm((PetscObject)this->mat,&this->comm);if (ierr) return;
28: }
31: esi::petsc::Matrix<double,int>::Matrix(Mat imat)
32: {
33: int m,n,M,N,ierr;
35: this->mat = imat;
36:
37: this->pobject = (PetscObject)this->mat;
38: PetscObjectGetComm((PetscObject)this->mat,&this->comm);if (ierr) return;
39: MatGetLocalSize(mat,&m,&n);if (ierr) return;
40: MatGetSize(mat,&M,&N);if (ierr) return;
41: this->rmap = new esi::petsc::IndexSpace<int>(this->comm,m,M);
42: this->cmap = new esi::petsc::IndexSpace<int>(this->comm,n,N);
43: }
46: esi::petsc::Matrix<double,int>::~Matrix()
47: {
49: MatDestroy(this->mat);if (ierr) return;
50: }
52: esi::ErrorCode esi::petsc::Matrix<double,int>::getInterface(const char* name, void *& iface)
53: {
54: PetscTruth flg;
56: if (!PetscStrcmp(name,"esi::Object",&flg),flg){
57: iface = (void *) (esi::Object *) this;
58: } else if (!PetscStrcmp(name,"esi::Operator",&flg),flg){
59: iface = (void *) (esi::Operator<double,int> *) this;
60: } else if (!PetscStrcmp(name,"esi::MatrixData",&flg),flg){
61: iface = (void *) (esi::MatrixData<int> *) this;
62: } else if (!PetscStrcmp(name,"esi::MatrixRowReadAccess",&flg),flg){
63: iface = (void *) (esi::MatrixRowReadAccess<double,int> *) this;
64: } else if (!PetscStrcmp(name,"esi::MatrixRowWriteAccess",&flg),flg){
65: iface = (void *) (esi::MatrixRowWriteAccess<double,int> *) this;
66: } else if (!PetscStrcmp(name,"esi::petsc::Matrix",&flg),flg){
67: iface = (void *) (esi::petsc::Matrix<double,int> *) this;
68: } else if (!PetscStrcmp(name,"Mat",&flg),flg){
69: iface = (void *) this->mat;
70: } else {
71: iface = 0;
72: }
73: return 0;
74: }
76: esi::ErrorCode esi::petsc::Matrix<double,int>::getInterfacesSupported(esi::Argv * list)
77: {
78: list->appendArg("esi::Object");
79: list->appendArg("esi::Operator");
80: list->appendArg("esi::MatrixData");
81: list->appendArg("esi::MatrixRowReadAccess");
82: list->appendArg("esi::MatrixRowWriteAccess");
83: list->appendArg("esi::petsc::Matrix");
84: list->appendArg("Mat");
85: return 0;
86: }
89: esi::ErrorCode esi::petsc::Matrix<double,int>::apply( esi::Vector<double,int> &xx,esi::Vector<double,int> &yy)
90: {
92: Vec py,px;
94: yy.getInterface("Vec",reinterpret_cast<void*&>(py));
95: xx.getInterface("Vec",reinterpret_cast<void*&>(px));
97: return MatMult(this->mat,px,py);
98: }
100: esi::ErrorCode esi::petsc::Matrix<double,int>::setup()
101: {
103: MatAssemblyBegin(this->mat,MAT_FINAL_ASSEMBLY);
104: return MatAssemblyEnd(this->mat,MAT_FINAL_ASSEMBLY);
105: }
107: esi::ErrorCode esi::petsc::Matrix<double,int>::getIndexSpaces(esi::IndexSpace<int>*& rowIndexSpace, esi::IndexSpace<int>*& colIndexSpace)
108: {
109: rowIndexSpace = this->rmap;
110: colIndexSpace = this->cmap;
111: return 0;
112: }
114: esi::ErrorCode esi::petsc::Matrix<double,int>::isLoaded(bool &State)
115: {
116: return MatAssembled(this->mat,(PetscTruth *)&State);
117: }
119: esi::ErrorCode esi::petsc::Matrix<double,int>::isAllocated(bool &State)
120: {
121: State = 1;
122: return 0;
123: }
125: esi::ErrorCode esi::petsc::Matrix<double,int>::loadComplete()
126: {
127: return this->setup();
128: }
130: esi::ErrorCode esi::petsc::Matrix<double,int>::allocate(int rowlengths[])
131: {
132: return 0;
133: }
135: esi::ErrorCode esi::petsc::Matrix<double,int>::getDiagonal(esi::Vector<double,int> &diagVector)
136: {
138: Vec py;
140: diagVector.getInterface("Vec",reinterpret_cast<void*&>(py));
141: return MatGetDiagonal(this->mat,py);
142: }
144: esi::ErrorCode esi::petsc::Matrix<double,int>::getGlobalSizes(int& rows, int& columns)
145: {
146: return MatGetSize(this->mat,&rows,&columns);
147: }
149: esi::ErrorCode esi::petsc::Matrix<double,int>::getLocalSizes(int& rows, int& columns)
150: {
151: return MatGetLocalSize(this->mat,&rows,&columns);
152: }
154: esi::ErrorCode esi::petsc::Matrix<double,int>::getRowNonzeros(int row,int &length)
155: {
156: int MatGetRow(this->mat,row,&length,PETSC_NULL,PETSC_NULL);
157: return MatRestoreRow(this->mat,row,&length,PETSC_NULL,PETSC_NULL);
158: }
160: esi::ErrorCode esi::petsc::Matrix<double,int>::setRowLength(int row,int length)
161: {
163: return 1;
164: }
166: esi::ErrorCode esi::petsc::Matrix<double,int>::copyOutRow(int row, double* coefs, int* colIndices,int alength,int &length)
167: {
168: int *col;
169: PetscScalar *values;
170:
171: int MatGetRow(this->mat,row,&length,&col,&values);
172: if (length > alength) SETERRQ(1,"Not enough room for values");
173: PetscMemcpy(coefs,values,length*sizeof(PetscScalar));
174: PetscMemcpy(colIndices,col,length*sizeof(int));
175: MatRestoreRow(this->mat,row,&length,&col,&values);
176: return(0);
177: }
179: esi::ErrorCode esi::petsc::Matrix<double,int>::getRow(int row, int& length, double*& coefs, int*& colIndices)
180: {
181: return MatGetRow(this->mat,row,&length,&colIndices,&coefs);
182: }
184: esi::ErrorCode esi::petsc::Matrix<double,int>::getRowCoefs(int row, int& length, double*& coefs)
185: {
186: return MatGetRow(this->mat,row,&length,PETSC_NULL,&coefs);
187: }
189: esi::ErrorCode esi::petsc::Matrix<double,int>::getRowIndices(int row, int& length, int*& colIndices)
190: {
191: return MatGetRow(this->mat,row,&length,&colIndices,PETSC_NULL);
192: }
194: esi::ErrorCode esi::petsc::Matrix<double,int>::restoreRow(int row, int& length, double*& coefs, int*& colIndices)
195: {
196: return MatRestoreRow(this->mat,row,&length,&colIndices,&coefs);
197: }
199: esi::ErrorCode esi::petsc::Matrix<double,int>::restoreRowCoefs(int row, int& length, double*& coefs)
200: {
201: return MatRestoreRow(this->mat,row,&length,PETSC_NULL,&coefs);
202: }
204: esi::ErrorCode esi::petsc::Matrix<double,int>::restoreRowIndices(int row, int& length, int*& colIndices)
205: {
206: return MatRestoreRow(this->mat,row,&length,&colIndices,PETSC_NULL);
207: }
209: esi::ErrorCode esi::petsc::Matrix<double,int>::copyIntoRow(int row,double* coefs, int* colIndices, int length)
210: {
211: return MatSetValues(this->mat,1,&row,length,colIndices,coefs,INSERT_VALUES);
212: }
214: esi::ErrorCode esi::petsc::Matrix<double,int>::sumIntoRow(int row, double* coefs, int* colIndices,int length)
215: {
216: return MatSetValues(this->mat,1,&row,length,colIndices,coefs,ADD_VALUES);
217: }
219: esi::ErrorCode esi::petsc::Matrix<double,int>::rowMax(int row, double &result)
220: {
221: int ierr,length,i;
222: PetscScalar *values;
224: MatGetRow(this->mat,row,&length,PETSC_NULL,&values);
225: if (values) {
226: result = values[0];
227: for (i=1; i<length; i++) result = PetscMax(result,values[i]);
228: }
229: MatRestoreRow(this->mat,row,&length,PETSC_NULL,&values);
230: return(0);
231: }
233: esi::ErrorCode esi::petsc::Matrix<double,int>::rowMin(int row, double &result)
234: {
235: int ierr,length,i;
236: PetscScalar *values;
238: MatGetRow(this->mat,row,&length,PETSC_NULL,&values);
239: if (values) {
240: result = values[0];
241: for (i=1; i<length; i++) result = PetscMin(result,values[i]);
242: }
243: MatRestoreRow(this->mat,row,&length,PETSC_NULL,&values);
244: return(0);
245: }
247: esi::ErrorCode esi::petsc::Matrix<double,int>::getRowSum(esi::Vector<double,int>& rowSumVector)
248: {
249: int i,ierr,rstart,rend,length,j;
250: PetscScalar *values,sum;
251: Vec py;
253: rowSumVector.getInterface("Vec",reinterpret_cast<void*&>(py));
255: MatGetOwnershipRange(this->mat,&rstart,&rend);
256: for ( i=rstart; i<rend; i++) {
257: MatGetRow(this->mat,i,&length,PETSC_NULL,&values);
258: sum = 0.0;
259: for ( j=0; j<length; j++ ) {
260: sum += values[j];
261: }
262: MatRestoreRow(this->mat,i,&length,PETSC_NULL,&values);
263: VecSetValues(py,1,&i,&sum,INSERT_VALUES);
264: }
265: VecAssemblyBegin(py);
266: VecAssemblyEnd(py);
268: return 0;
269: }
271: /* ------------------------------------------------------------------------------------------------*/
273: namespace esi{namespace petsc{
274: template<class Scalar,class Ordinal> class OperatorFactory : public virtual ::esi::OperatorFactory<Scalar,Ordinal>
275: {
276: public:
278: // constructor
279: OperatorFactory(void){};
280:
281: // Destructor.
282: virtual ~OperatorFactory(void){};
284: // Interface for gov::cca::Component
285: #if defined(PETSC_HAVE_CCA)
286: virtual void setServices(gov::cca::Services *svc)
287: {
288: svc->addProvidesPort(this,svc->createPortInfo("getOperator", "esi::OperatorFactory", 0));
289: };
290: #endif
292: // Construct a Operator
293: virtual ::esi::ErrorCode getOperator(::esi::IndexSpace<Ordinal>&rmap,::esi::IndexSpace<Ordinal>&cmap,::esi::Operator<Scalar,Ordinal>*&v)
294: {
295: v = new esi::petsc::Matrix<Scalar,Ordinal>(&rmap,&cmap);
296: return 0;
297: };
298: };
299: }}
301: ::esi::petsc::OperatorFactory<double,int> OFInstForIntel64CompilerBug;
303: EXTERN_C_BEGIN
304: #if defined(PETSC_HAVE_CCA)
305: gov::cca::Component *create_esi_petsc_operatorfactory(void)
306: {
307: return dynamic_cast<gov::cca::Component *>(new esi::petsc::OperatorFactory<double,int>);
308: }
309: #else
310: ::esi::OperatorFactory<double,int> *create_esi_petsc_operatorfactory(void)
311: {
312: return dynamic_cast< ::esi::OperatorFactory<double,int> *>(new esi::petsc::OperatorFactory<double,int>);
313: }
314: #endif
315: EXTERN_C_END
318: #if defined(PETSC_HAVE_TRILINOS)
319: #include esi/petsc/matrix.h
320: #define PETRA_MPI /* used by Ptera to indicate MPI code */
321: #include "Petra_ESI_CRS_Matrix.h"
323: /*
324: This class is the same as the Petra_ESI_CRS_Matrix class except it puts values into the Petra_CRS_Grap()
325: */
326: template<class Scalar,class Ordinal> class MyPetra_ESI_CRS_Matrix : public virtual Petra_ESI_CRS_Matrix<Scalar,Ordinal>
327: {
328: public:
330: MyPetra_ESI_CRS_Matrix(Petra_DataAccess CV,const Petra_CRS_Graph& graph) : Petra_ESI_Object(), Petra_RDP_CRS_Matrix(CV, graph), Petra_ESI_CRS_Matrix<Scalar,Ordinal>(CV, graph){graph_ = (Petra_CRS_Graph*)&graph;SetStaticGraph(false);};
332: virtual ~MyPetra_ESI_CRS_Matrix(void) { };
334: virtual esi::ErrorCode copyIntoRow(Ordinal row, Scalar* coefs, Ordinal* colIndices, Ordinal length)
336: graph_->InsertGlobalIndices(row, length, colIndices);CHKERRQ(((ierr == 1) ? 0 : ierr));
337: Petra_ESI_CRS_Matrix<Scalar,Ordinal>::copyIntoRow(row,coefs,colIndices,length);
338: // this->setup();
339: return 0;
340: }
342: Petra_CRS_Graph *graph_;
343: };
346: template<class Scalar,class Ordinal> class Petra_ESI_CRS_OperatorFactory : public virtual ::esi::OperatorFactory<Scalar,Ordinal>
347: {
348: public:
350: // constructor
351: Petra_ESI_CRS_OperatorFactory(void){};
352:
353: // Destructor.
354: virtual ~Petra_ESI_CRS_OperatorFactory(void){};
356: // Interface for gov::cca::Component
357: #if defined(PETSC_HAVE_CCA)
358: virtual void setServices(gov::cca::Services *svc)
359: {
360: svc->addProvidesPort(this,svc->createPortInfo("getOperator", "esi::OperatorFactory", 0));
361: };
362: #endif
364: // Construct a Operator
365: virtual ::esi::ErrorCode getOperator(::esi::IndexSpace<Ordinal>&rmap,::esi::IndexSpace<Ordinal>&cmap,::esi::Operator<Scalar,Ordinal>*&v)
366: {
367: int ierr;
368: Petra_Map *rowmap,*colmap;
369: rmap.getInterface("Petra_Map",reinterpret_cast<void *&>(rowmap));
370: if (!rowmap) SETERRQ(1,"Petra requires all IndexSpaces be Petra_ESI_IndexSpaces");
371: cmap.getInterface("Petra_Map",reinterpret_cast<void *&>(colmap));
372: if (!colmap) SETERRQ(1,"Petra requires all IndexSpaces be Petra_ESI_IndexSpaces");
373: Petra_CRS_Graph *graph = new Petra_CRS_Graph(Copy,*(Petra_BlockMap*)rowmap,*(Petra_BlockMap*)colmap,200);
374: rmap.addReference();
375: cmap.addReference();
376: v = new MyPetra_ESI_CRS_Matrix<Scalar,Ordinal>(Copy,*graph);
377: return 0;
378: };
379: };
381: EXTERN_C_BEGIN
382: #if defined(PETSC_HAVE_CCA)
383: gov::cca::Component *create_petra_esi_operatorfactory(void)
384: {
385: return dynamic_cast<gov::cca::Component *>(new Petra_ESI_CRS_OperatorFactory<double,int>);
386: }
387: #else
388: ::esi::OperatorFactory<double,int> *create_petra_esi_operatorfactory(void)
389: {
390: return dynamic_cast< ::esi::OperatorFactory<double,int> *>(new Petra_ESI_CRS_OperatorFactory<double,int>);
391: }
392: #endif
393: EXTERN_C_END
394: #endif
398: