1 #ifndef lint 2 static char vcid[] = "$Id: shell.c,v 1.9 1995/05/11 03:46:44 curfman 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 mush 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; 17 int (*mult)(void *,Vec,Vec); 18 int (*multtransadd)(void*,Vec,Vec,Vec); 19 void *ctx; 20 } MatShell; 21 22 static int MatShellMult(Mat mat,Vec x,Vec y) 23 { 24 MatShell *shell; 25 shell = (MatShell *) mat->data; 26 return (*shell->mult)(shell->ctx,x,y); 27 } 28 static int MatShellMultTransAdd(Mat mat,Vec x,Vec y,Vec z) 29 { 30 MatShell *shell; 31 shell = (MatShell *) mat->data; 32 return (*shell->multtransadd)(shell->ctx,x,y,z); 33 } 34 static int MatShellDestroy(PetscObject obj) 35 { 36 Mat mat = (Mat) obj; 37 MatShell *shell; 38 shell = (MatShell *) mat->data; 39 PETSCFREE(shell); 40 PLogObjectDestroy(mat); 41 PETSCHEADERDESTROY(mat); 42 return 0; 43 } 44 45 static struct _MatOps MatOps = {0,0, 46 0, 47 MatShellMult,0,0,MatShellMultTransAdd, 48 0,0,0,0, 49 0,0, 50 0, 51 0, 52 0,0,0, 53 0, 54 0,0,0, 55 0,0, 56 0, 57 0,0,0,0, 58 0,0 }; 59 60 /*@ 61 MatShellCreate - Creates a new matrix class for use with a user-defined 62 private data storage format. 63 64 Input Parameters: 65 . comm - MPI communicator 66 . m - number of rows 67 . n - number of columns 68 . ctx - pointer to data needed by matrix-vector multiplication routine(s) 69 70 Output Parameter: 71 . mat - the matrix 72 73 Notes: 74 The shell matrix type is intended to provide a simple class to use 75 with KSP (such as, for use with matrix-free methods). You should not 76 use the shell type if you plan to define a complete matrix class. 77 78 Usage: 79 $ MatShellCreate(m,n,ctx,&mat); 80 $ MatShellSetMult(mat,mult); 81 82 .keywords: matrix, shell, create 83 84 .seealso: MatShellSetMult(), MatShellSetMultTransAdd() 85 @*/ 86 int MatShellCreate(MPI_Comm comm,int m, int n, void *ctx,Mat *mat) 87 { 88 Mat newmat; 89 MatShell *shell; 90 PETSCHEADERCREATE(newmat,_Mat,MAT_COOKIE,MATSHELL,comm); 91 PLogObjectCreate(newmat); 92 *mat = newmat; 93 newmat->factor = 0; 94 newmat->destroy= MatShellDestroy; 95 newmat->ops = &MatOps; 96 shell = PETSCNEW(MatShell); CHKPTRQ(shell); 97 newmat->data = (void *) shell; 98 shell->mult = 0; 99 shell->m = m; 100 shell->n = n; 101 shell->ctx = ctx; 102 return 0; 103 } 104 105 /*@ 106 MatShellSetMult - Sets the routine for computing the matrix-vector product. 107 108 Input Parameters: 109 . mat - the matrix associated with this operation, created 110 with MatShellCreate() 111 . mult - the user-defined routine 112 113 Calling sequence of mult: 114 int mult (void *ptr,Vec xin,Vec xout) 115 . ptr - the application context for matrix data 116 . xin - input vector 117 . xout - output vector 118 119 .keywords: matrix, multiply, shell, set 120 121 .seealso: MatShellCreate(), MatShellSetMultTransAdd() 122 @*/ 123 int MatShellSetMult(Mat mat, int (*mult)(void*,Vec,Vec)) 124 { 125 MatShell *shell; 126 VALIDHEADER(mat,MAT_COOKIE); 127 shell = (MatShell *) mat->data; 128 shell->mult = mult; 129 return 0; 130 } 131 /*@ 132 MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1. 133 134 Input Parameters: 135 . mat - the matrix associated with this operation, created 136 with MatShellCreate() 137 . mult - the user-defined routine 138 139 Calling sequence of mult: 140 int mult (void *ptr,Vec v1,Vec v2,Vec v3) 141 . ptr - the application context for matrix data 142 . v1, v2 - the input vectors 143 . v3 - the result 144 145 .keywords: matrix, multiply, transpose 146 147 .seealso: MatShellCreate(), MatShellSetMult() 148 @*/ 149 int MatShellSetMultTransAdd(Mat mat, int (*mult)(void*,Vec,Vec,Vec)) 150 { 151 MatShell *shell; 152 VALIDHEADER(mat,MAT_COOKIE); 153 shell = (MatShell *) mat->data; 154 shell->multtransadd = mult; 155 return 0; 156 } 157 158 159