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