1 #define PETSCMAT_DLL 2 3 /* 4 Provides an interface for the Matlab engine sparse solver 5 6 */ 7 #include "src/mat/impls/aij/seq/aij.h" 8 9 #include "engine.h" /* Matlab include file */ 10 #include "mex.h" /* Matlab include file */ 11 12 13 EXTERN_C_BEGIN 14 #undef __FUNCT__ 15 #define __FUNCT__ "MatMatlabEnginePut_Matlab" 16 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine) 17 { 18 PetscErrorCode ierr; 19 Mat B = (Mat)obj; 20 mxArray *mat; 21 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 22 23 PetscFunctionBegin; 24 mat = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL); 25 ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 26 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 27 ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 28 ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr); 29 30 /* Matlab indices start at 0 for sparse (what a surprise) */ 31 32 ierr = PetscObjectName(obj);CHKERRQ(ierr); 33 engPutVariable((Engine *)mengine,obj->name,mat); 34 PetscFunctionReturn(0); 35 } 36 EXTERN_C_END 37 38 EXTERN_C_BEGIN 39 #undef __FUNCT__ 40 #define __FUNCT__ "MatMatlabEngineGet_Matlab" 41 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine) 42 { 43 PetscErrorCode ierr; 44 int ii; 45 Mat mat = (Mat)obj; 46 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 47 mxArray *mmat; 48 49 PetscFunctionBegin; 50 ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 51 52 mmat = engGetVariable((Engine *)mengine,obj->name); 53 54 aij->nz = (mxGetJc(mmat))[mat->rmap.n]; 55 ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr); 56 aij->singlemalloc = PETSC_TRUE; 57 58 ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 59 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 60 ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 61 ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr); 62 63 for (ii=0; ii<mat->rmap.n; ii++) { 64 aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 65 } 66 67 ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 68 ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69 70 PetscFunctionReturn(0); 71 } 72 EXTERN_C_END 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "MatSolve_Matlab" 76 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 77 { 78 PetscErrorCode ierr; 79 const char *_A,*_b,*_x; 80 81 PetscFunctionBegin; 82 /* make sure objects have names; use default if not */ 83 ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 84 ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 85 86 ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 87 ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 88 ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 89 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 90 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 91 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 92 /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 93 ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "MatLUFactorNumeric_Matlab" 99 PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F) 100 { 101 PetscErrorCode ierr; 102 size_t len; 103 char *_A,*name; 104 105 PetscFunctionBegin; 106 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 107 _A = A->name; 108 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr); 109 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 110 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 111 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 112 sprintf(name,"_%s",_A); 113 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 114 ierr = PetscFree(name);CHKERRQ(ierr); 115 PetscFunctionReturn(0); 116 } 117 118 #undef __FUNCT__ 119 #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 120 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 121 { 122 PetscErrorCode ierr; 123 124 PetscFunctionBegin; 125 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 126 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 127 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 128 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 129 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 130 (*F)->ops->solve = MatSolve_Matlab; 131 (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 132 (*F)->factor = MAT_FACTOR_LU; 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNCT__ 137 #define __FUNCT__ "MatGetFactor_seqaij_matlab" 138 PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 139 { 140 PetscErrorCode ierr; 141 142 PetscFunctionBegin; 143 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 144 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 145 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 146 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 147 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 148 (*F)->ops->solve = MatSolve_Matlab; 149 (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 150 (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 151 (*F)->factor = MAT_FACTOR_LU; 152 PetscFunctionReturn(0); 153 } 154 155 156 /* --------------------------------------------------------------------------------*/ 157 #undef __FUNCT__ 158 #define __FUNCT__ "MatILUDTFactor_Matlab" 159 PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F) 160 { 161 PetscErrorCode ierr; 162 size_t len; 163 char *_A,*name; 164 165 PetscFunctionBegin; 166 if (info->dt == PETSC_DEFAULT) info->dt = .005; 167 if (info->dtcol == PETSC_DEFAULT) info->dtcol = .01; 168 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 169 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 170 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 171 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 172 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 173 (*F)->ops->solve = MatSolve_Matlab; 174 (*F)->factor = MAT_FACTOR_LU; 175 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 176 _A = A->name; 177 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr); 178 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr); 179 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 180 181 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 182 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 183 sprintf(name,"_%s",_A); 184 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 185 ierr = PetscFree(name);CHKERRQ(ierr); 186 PetscFunctionReturn(0); 187 } 188 189 #undef __FUNCT__ 190 #define __FUNCT__ "MatFactorInfo_Matlab" 191 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 192 { 193 PetscErrorCode ierr; 194 195 PetscFunctionBegin; 196 ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 197 PetscFunctionReturn(0); 198 } 199 200 #undef __FUNCT__ 201 #define __FUNCT__ "MatView_Matlab" 202 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 203 { 204 PetscErrorCode ierr; 205 PetscTruth iascii; 206 PetscViewerFormat format; 207 Mat_Matlab *lu=(Mat_Matlab*)(A->spptr); 208 209 PetscFunctionBegin; 210 ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 211 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 212 if (iascii) { 213 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 214 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 215 ierr = MatFactorInfo_Matlab(A,viewer); 216 } 217 } 218 PetscFunctionReturn(0); 219 } 220 221 222 /*MC 223 MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance 224 based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 225 226 If Matlab is instaled (see the manual for 227 instructions on how to declare the existence of external packages), 228 a matrix type can be constructed which invokes Matlab solvers. 229 After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB). 230 This matrix type is only supported for double precision real. 231 232 This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 233 supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 234 the MATSEQAIJ type without data copy. 235 236 Options Database Keys: 237 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions() 238 - -mat_matlab_qr - sets the direct solver to be QR instead of LU 239 240 Level: beginner 241 242 .seealso: PCLU 243 M*/ 244 245