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,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,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,MatFactorInfo *info,Mat *F) 153 { 154 PetscErrorCode ierr; 155 size_t len; 156 char *_A,*name; 157 158 PetscFunctionBegin; 159 if (info->dt == PETSC_DEFAULT) info->dt = .005; 160 if (info->dtcol == PETSC_DEFAULT) info->dtcol = .01; 161 if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 162 ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 163 ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 164 ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 165 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 166 (*F)->ops->solve = MatSolve_Matlab; 167 (*F)->factor = MAT_FACTOR_LU; 168 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 169 _A = ((PetscObject)A)->name; 170 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr); 171 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); 172 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 173 174 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 175 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 176 sprintf(name,"_%s",_A); 177 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 178 ierr = PetscFree(name);CHKERRQ(ierr); 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "MatFactorInfo_Matlab" 184 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 185 { 186 PetscErrorCode ierr; 187 188 PetscFunctionBegin; 189 ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 190 PetscFunctionReturn(0); 191 } 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "MatView_Matlab" 195 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 196 { 197 PetscErrorCode ierr; 198 PetscTruth iascii; 199 PetscViewerFormat format; 200 201 PetscFunctionBegin; 202 ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 203 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 204 if (iascii) { 205 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 206 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 207 ierr = MatFactorInfo_Matlab(A,viewer); 208 } 209 } 210 PetscFunctionReturn(0); 211 } 212 213 214 /*MC 215 MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance 216 based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 217 218 If Matlab is instaled (see the manual for 219 instructions on how to declare the existence of external packages), 220 a matrix type can be constructed which invokes Matlab solvers. 221 After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB). 222 This matrix type is only supported for double precision real. 223 224 This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 225 supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 226 the MATSEQAIJ type without data copy. 227 228 Options Database Keys: 229 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions() 230 - -mat_matlab_qr - sets the direct solver to be QR instead of LU 231 232 Level: beginner 233 234 .seealso: PCLU 235 M*/ 236 237