Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

blockDiag.C

Go to the documentation of this file.
00001 
00007 #include "petscmat.h"
00008 #include "petscpc.h"
00009 #include "private/pcimpl.h"
00010 #include "blockDiag.h"
00011 #include <cassert>
00012 
00013 namespace ot {
00014 
00015   extern void (*getDofAndNodeSizeForPC_BlockDiag)(Mat pcMat,
00016       unsigned int & dof, unsigned int & nodeSize);
00017 
00018   extern void (*computeInvBlockDiagEntriesForPC_BlockDiag)(Mat pcMat,
00019       double **invBlockDiagEntries);
00020 
00021 
00022   PetscErrorCode PCSetUp_BlockDiag(PC pc) {
00023 
00024     PetscFunctionBegin;
00025     PC_BlockDiag* data = static_cast<PC_BlockDiag*>(pc->data);
00026 
00027     Mat pcMat = pc->pmat;
00028     PetscTruth isshell;
00029     PetscTypeCompare((PetscObject)pcMat, MATSHELL, &isshell);
00030 
00031     if(!isshell) {
00032       SETERRQ(PETSC_ERR_SUP," Expected a MATSHELL.");
00033       assert(false);
00034     }
00035 
00036     if(pc->setupcalled == 0) {
00037       if(getDofAndNodeSizeForPC_BlockDiag) {
00038         (*getDofAndNodeSizeForPC_BlockDiag)(pcMat, data->dof, data->nodeSize);
00039       } else {
00040         SETERRQ(PETSC_ERR_USER," Expected function to be set: getDofAndNodeSizeForPC_BlockDiag");
00041         assert(false);
00042       }
00043 
00044       //Allocate memory
00045       assert(data->invBlockDiagEntries == NULL);
00046       if((data->dof) && (data->nodeSize)) {
00047         typedef double* doublePtr;
00048         data->invBlockDiagEntries = new doublePtr[(data->dof)*(data->nodeSize)];
00049         for(int i = 0; i < ((data->dof)*(data->nodeSize)); i++) {
00050           data->invBlockDiagEntries[i] = new double[data->dof];
00051         }
00052         PetscLogObjectMemory(pc, (((data->dof)*(data->nodeSize))*sizeof(double)));
00053       }
00054     }
00055 
00056     if(computeInvBlockDiagEntriesForPC_BlockDiag) {
00057       (*computeInvBlockDiagEntriesForPC_BlockDiag)(pcMat, data->invBlockDiagEntries);
00058     } else {
00059       SETERRQ(PETSC_ERR_USER,
00060           " Expected function to be set: computeInvBlockDiagEntriesForPC_BlockDiag");
00061       assert(false);
00062     }
00063 
00064     PetscFunctionReturn(0);
00065   }
00066 
00067   PetscErrorCode PCApply_BlockDiag(PC pc, Vec x, Vec y) {
00068 
00069     PetscFunctionBegin;
00070     PC_BlockDiag* data = static_cast<PC_BlockDiag*>(pc->data);
00071 
00072     //y = invBlockDiagEntries*x
00073     VecZeroEntries(y);
00074     PetscScalar *yArr = NULL;
00075     PetscScalar *xArr = NULL;
00076     VecGetArray(y, &yArr);
00077     VecGetArray(x, &xArr);
00078     for(int i = 0; i < data->nodeSize; i++) {
00079       for(int j = 0; j < data->dof; j++) {
00080         for(int k = 0; k < data->dof; k++) {
00081           yArr[((data->dof)*i) + j] += 
00082             ((data->invBlockDiagEntries[((data->dof)*i) + j][k])*
00083              xArr[((data->dof)*i) + k]);
00084         }
00085       }
00086     }
00087     VecRestoreArray(y, &yArr);
00088     VecRestoreArray(x, &xArr);
00089 
00090     PetscFunctionReturn(0);
00091   }
00092 
00093   PetscErrorCode PCCreate_BlockDiag(PC pc) {
00094 
00095     PetscFunctionBegin;
00096     PC_BlockDiag* data = new PC_BlockDiag;
00097 
00098     pc->data = (void*)(data);
00099 
00100     PetscLogObjectMemory(pc, sizeof(PC_BlockDiag));
00101 
00102     //Initialize Data
00103     data->dof = 0;
00104     data->nodeSize = 0;
00105     data->invBlockDiagEntries = NULL;
00106 
00107     pc->ops->apply = PCApply_BlockDiag;
00108     pc->ops->setup = PCSetUp_BlockDiag;
00109     pc->ops->destroy = PCDestroy_BlockDiag;
00110     pc->ops->setfromoptions = PCSetFromOptions_BlockDiag;
00111     pc->ops->applytranspose = NULL;
00112     pc->ops->view = NULL;
00113     pc->ops->applyrichardson = NULL;
00114     pc->ops->applysymmetricleft = NULL;
00115     pc->ops->applysymmetricright = NULL;
00116 
00117     PetscFunctionReturn(0);
00118   }
00119 
00120   PetscErrorCode PCDestroy_BlockDiag(PC pc) {
00121 
00122     PetscFunctionBegin;
00123     PC_BlockDiag* data = static_cast<PC_BlockDiag*>(pc->data);
00124 
00125     if(data) {
00126 
00127       if(data->invBlockDiagEntries) {
00128         for(int i = 0; i < ((data->dof)*(data->nodeSize)); i++) {
00129           delete [] (data->invBlockDiagEntries[i]);
00130           data->invBlockDiagEntries[i] = NULL;
00131         }
00132         delete [] (data->invBlockDiagEntries);
00133         data->invBlockDiagEntries = NULL;
00134       }
00135 
00136       delete data;
00137       data = NULL;
00138 
00139     }
00140 
00141     PetscFunctionReturn(0);
00142   }
00143 
00144   PetscErrorCode PCSetFromOptions_BlockDiag(PC pc) {
00145     PetscFunctionBegin;
00146     PetscFunctionReturn(0);
00147   }
00148 
00149 } //end namespace 
00150 
00151 

Generated on Tue Mar 24 16:14:07 2009 for DENDRO by  doxygen 1.3.9.1