1 #ifndef lint 2 static char vcid[] = "$Id: shell.c,v 1.22 1995/11/03 03:00:36 bsmith Exp bsmith $"; 3 #endif 4 5 /* 6 This provides a simple shell for Fortran (and C programmers) to 7 create a very simple matrix class for use with KSP without coding 8 much of anything. 9 */ 10 11 #include "petsc.h" 12 #include "matimpl.h" /*I "mat.h" I*/ 13 #include "vec/vecimpl.h" 14 15 typedef struct { 16 int m, n; /* rows, columns */ 17 int (*mult)(void*,Vec,Vec); 18 int (*multtransadd)(void*,Vec,Vec,Vec); 19 int (*destroy)(void*); 20 int (*getsize)(void*,int*,int*); 21 void *ctx; 22 } Mat_Shell; 23 24 /*@ 25 MatShellGetContext - Returns the user provided context associated 26 with a MatShell. 27 28 Input Parameter: 29 . mat - the matrix, should have been created with MatCreateShell() 30 31 Output Parameter: 32 . ctx - the user provided context 33 34 @*/ 35 int MatShellGetContext(Mat mat,void **ctx) 36 { 37 PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 38 if (mat->type != MATSHELL) *ctx = 0; 39 else *ctx = ((Mat_Shell *) (mat->data))->ctx; 40 return 0; 41 } 42 43 static int MatGetSize_Shell(Mat mat,int *m,int *n) 44 { 45 Mat_Shell *shell = (Mat_Shell *) mat->data; 46 *m = shell->m; *n = shell->n; 47 return 0; 48 } 49 50 static int MatMult_Shell(Mat mat,Vec x,Vec y) 51 { 52 Mat_Shell *shell = (Mat_Shell *) mat->data; 53 return (*shell->mult)(shell->ctx,x,y); 54 } 55 56 static int MatMultTransAdd_Shell(Mat mat,Vec x,Vec y,Vec z) 57 { 58 Mat_Shell *shell = (Mat_Shell *) mat->data; 59 return (*shell->multtransadd)(shell->ctx,x,y,z); 60 } 61 62 static int MatDestroy_Shell(PetscObject obj) 63 { 64 int ierr; 65 Mat mat = (Mat) obj; 66 Mat_Shell *shell; 67 68 shell = (Mat_Shell *) mat->data; 69 if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);} 70 PetscFree(shell); 71 PLogObjectDestroy(mat); 72 PetscHeaderDestroy(mat); 73 return 0; 74 } 75 76 static struct _MatOps MatOps = {0,0, 77 0, 78 MatMult_Shell,0,0,MatMultTransAdd_Shell, 79 0,0,0,0, 80 0,0, 81 0, 82 0, 83 0,0,0, 84 0, 85 0,0,0, 86 0,0, 87 0, 88 0,0,0,0, 89 0,0,MatGetSize_Shell, 90 0,0,0,0, 91 0,0,0,0 }; 92 93 /*@C 94 MatShellCreate - Creates a new matrix class for use with a user-defined 95 private data storage format. 96 97 Input Parameters: 98 . comm - MPI communicator 99 . m - number of rows 100 . n - number of columns 101 . ctx - pointer to data needed by matrix-vector multiplication routine(s) 102 103 Output Parameter: 104 . mat - the matrix 105 106 Notes: 107 The shell matrix type is intended to provide a simple class to use 108 with KSP (such as, for use with matrix-free methods). You should not 109 use the shell type if you plan to define a complete matrix class. 110 111 Usage: 112 $ MatShellCreate(m,n,ctx,&mat); 113 $ MatShellSetMult(mat,mult); 114 115 .keywords: matrix, shell, create 116 117 .seealso: MatShellSetMult(), MatShellSetMultTransAdd() 118 @*/ 119 int MatShellCreate(MPI_Comm comm,int m,int n,void *ctx,Mat *mat) 120 { 121 Mat newmat; 122 Mat_Shell *shell; 123 124 PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm); 125 PLogObjectCreate(newmat); 126 *mat = newmat; 127 newmat->factor = 0; 128 newmat->destroy= MatDestroy_Shell; 129 PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps)); 130 shell = PetscNew(Mat_Shell); CHKPTRQ(shell); 131 PetscMemzero(shell,sizeof(Mat_Shell)); 132 newmat->data = (void *) shell; 133 shell->mult = 0; 134 shell->m = m; 135 shell->n = n; 136 shell->ctx = ctx; 137 return 0; 138 } 139 140 /*@C 141 MatShellSetMult - Sets the routine for computing the matrix-vector product. 142 143 Input Parameters: 144 . mat - the matrix associated with this operation, created 145 with MatShellCreate() 146 . mult - the user-defined routine 147 148 Calling sequence of mult: 149 int mult (void *ptr,Vec xin,Vec xout) 150 . ptr - the application context for matrix data 151 . xin - input vector 152 . xout - output vector 153 154 .keywords: matrix, multiply, shell, set 155 156 .seealso: MatShellCreate(), MatShellSetMultTransAdd() 157 @*/ 158 int MatShellSetMult(Mat mat,int (*mult)(void*,Vec,Vec)) 159 { 160 Mat_Shell *shell; 161 PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 162 shell = (Mat_Shell *) mat->data; 163 shell->mult = mult; 164 return 0; 165 } 166 /*@C 167 MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1. 168 169 Input Parameters: 170 . mat - the matrix associated with this operation, created 171 with MatShellCreate() 172 . mult - the user-defined routine 173 174 Calling sequence of mult: 175 int mult (void *ptr,Vec v1,Vec v2,Vec v3) 176 . ptr - the application context for matrix data 177 . v1, v2 - the input vectors 178 . v3 - the result 179 180 .keywords: matrix, multiply, transpose 181 182 .seealso: MatShellCreate(), MatShellSetMult() 183 @*/ 184 int MatShellSetMultTransAdd(Mat mat,int (*mult)(void*,Vec,Vec,Vec)) 185 { 186 Mat_Shell *shell; 187 PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 188 shell = (Mat_Shell *) mat->data; 189 shell->multtransadd = mult; 190 return 0; 191 } 192 /*@C 193 MatShellSetDestroy - Set the routine to use to destroy the 194 private contents of your MatShell. 195 196 Input Parameters: 197 . mat - the matrix associated with this operation, created 198 with MatShellCreate() 199 . destroy - the user-defined routine 200 201 Calling sequence of mult: 202 int destroy (void *ptr) 203 . ptr - the application context for matrix data 204 205 .keywords: matrix, destroy, shell, set 206 207 .seealso: MatShellCreate() 208 @*/ 209 int MatShellSetDestroy(Mat mat,int (*destroy)(void*)) 210 { 211 Mat_Shell *shell; 212 PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 213 shell = (Mat_Shell *) mat->data; 214 shell->destroy = destroy; 215 return 0; 216 } 217 218 219