1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 33b3e256bSKris Buschelman /* 43b3e256bSKris Buschelman Provides an interface for the Matlab engine sparse solver 53b3e256bSKris Buschelman 63b3e256bSKris Buschelman */ 7*7c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h" 83b3e256bSKris Buschelman 93b3e256bSKris Buschelman #include "engine.h" /* Matlab include file */ 103b3e256bSKris Buschelman #include "mex.h" /* Matlab include file */ 113b3e256bSKris Buschelman 12a1d52234SKris Buschelman 13a1d52234SKris Buschelman EXTERN_C_BEGIN 14a1d52234SKris Buschelman #undef __FUNCT__ 15a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEnginePut_Matlab" 16be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine) 17a1d52234SKris Buschelman { 18dfbe8321SBarry Smith PetscErrorCode ierr; 19a1d52234SKris Buschelman Mat B = (Mat)obj; 20a1d52234SKris Buschelman mxArray *mat; 21a1d52234SKris Buschelman Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 22a1d52234SKris Buschelman 23a1d52234SKris Buschelman PetscFunctionBegin; 24f0523c5fSHong Zhang mat = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL); 25f0523c5fSHong Zhang //mat = mxCreateSparse(((PetscObject)B)->cmap.n,((PetscObject)B)->rmap.n,((Mat_SeqAIJ*)aij)->nz,mxREAL); 26a1d52234SKris Buschelman ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 27a1d52234SKris Buschelman /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 28a1d52234SKris Buschelman ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 29f0523c5fSHong Zhang ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap->n+1)*sizeof(int));CHKERRQ(ierr); 30a1d52234SKris Buschelman 31a1d52234SKris Buschelman /* Matlab indices start at 0 for sparse (what a surprise) */ 32a1d52234SKris Buschelman 33a1d52234SKris Buschelman ierr = PetscObjectName(obj);CHKERRQ(ierr); 34a1d52234SKris Buschelman engPutVariable((Engine *)mengine,obj->name,mat); 35a1d52234SKris Buschelman PetscFunctionReturn(0); 36a1d52234SKris Buschelman } 37a1d52234SKris Buschelman EXTERN_C_END 38a1d52234SKris Buschelman 39a1d52234SKris Buschelman EXTERN_C_BEGIN 40a1d52234SKris Buschelman #undef __FUNCT__ 41a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab" 42be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine) 43a1d52234SKris Buschelman { 44dfbe8321SBarry Smith PetscErrorCode ierr; 45dfbe8321SBarry Smith int ii; 46a1d52234SKris Buschelman Mat mat = (Mat)obj; 47a1d52234SKris Buschelman Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 48a1d52234SKris Buschelman mxArray *mmat; 49a1d52234SKris Buschelman 50a1d52234SKris Buschelman PetscFunctionBegin; 511f03425eSSatish Balay ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 52a1d52234SKris Buschelman 53a1d52234SKris Buschelman mmat = engGetVariable((Engine *)mengine,obj->name); 54a1d52234SKris Buschelman 55f0523c5fSHong Zhang aij->nz = (mxGetJc(mmat))[mat->rmap->n]; 56f0523c5fSHong Zhang ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); 57a1d52234SKris Buschelman aij->singlemalloc = PETSC_TRUE; 58a1d52234SKris Buschelman 59a1d52234SKris Buschelman ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 60a1d52234SKris Buschelman /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 61a1d52234SKris Buschelman ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 62f0523c5fSHong Zhang ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap->n+1)*sizeof(int));CHKERRQ(ierr); 63a1d52234SKris Buschelman 64f0523c5fSHong Zhang for (ii=0; ii<mat->rmap->n; ii++) { 65a1d52234SKris Buschelman aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 66a1d52234SKris Buschelman } 67a1d52234SKris Buschelman 68a1d52234SKris Buschelman ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69a1d52234SKris Buschelman ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70a1d52234SKris Buschelman 71a1d52234SKris Buschelman PetscFunctionReturn(0); 72a1d52234SKris Buschelman } 73a1d52234SKris Buschelman EXTERN_C_END 74a1d52234SKris Buschelman 7505db81ecSKris Buschelman #undef __FUNCT__ 7605db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab" 77dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 783b3e256bSKris Buschelman { 79dfbe8321SBarry Smith PetscErrorCode ierr; 80e060cb09SBarry Smith const char *_A,*_b,*_x; 813b3e256bSKris Buschelman 823b3e256bSKris Buschelman PetscFunctionBegin; 833b3e256bSKris Buschelman /* make sure objects have names; use default if not */ 843b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 853b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 863b3e256bSKris Buschelman 873b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 883b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 893b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 907adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 917adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 927adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 937adad957SLisandro Dalcin /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 947adad957SLisandro Dalcin ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 953b3e256bSKris Buschelman PetscFunctionReturn(0); 963b3e256bSKris Buschelman } 973b3e256bSKris Buschelman 983b3e256bSKris Buschelman #undef __FUNCT__ 9905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab" 1000481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 1013b3e256bSKris Buschelman { 102dfbe8321SBarry Smith PetscErrorCode ierr; 103de4209c5SBarry Smith size_t len; 1043b3e256bSKris Buschelman char *_A,*name; 1053b3e256bSKris Buschelman 1063b3e256bSKris Buschelman PetscFunctionBegin; 1077adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 108f0523c5fSHong Zhang _A = ((PetscObject)A)->name; 1097adad957SLisandro Dalcin 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); 1107adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 1113b3e256bSKris Buschelman ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 1123b3e256bSKris Buschelman ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 1133b3e256bSKris Buschelman sprintf(name,"_%s",_A); 114f0523c5fSHong Zhang ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 1153b3e256bSKris Buschelman ierr = PetscFree(name);CHKERRQ(ierr); 116f0523c5fSHong Zhang F->ops->solve = MatSolve_Matlab; 1173b3e256bSKris Buschelman PetscFunctionReturn(0); 1183b3e256bSKris Buschelman } 1193b3e256bSKris Buschelman 1203b3e256bSKris Buschelman #undef __FUNCT__ 12105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 1220481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 1233b3e256bSKris Buschelman { 1243b3e256bSKris Buschelman PetscFunctionBegin; 125f0523c5fSHong Zhang if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 126f0523c5fSHong Zhang F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 1273b3e256bSKris Buschelman PetscFunctionReturn(0); 1283b3e256bSKris Buschelman } 1293b3e256bSKris Buschelman 13035bd34faSBarry Smith EXTERN_C_BEGIN 13135bd34faSBarry Smith #undef __FUNCT__ 13235bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 13335bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 13435bd34faSBarry Smith { 13535bd34faSBarry Smith PetscFunctionBegin; 13635bd34faSBarry Smith *type = MAT_SOLVER_MATLAB; 13735bd34faSBarry Smith PetscFunctionReturn(0); 13835bd34faSBarry Smith } 13935bd34faSBarry Smith EXTERN_C_END 14035bd34faSBarry Smith 1413b3e256bSKris Buschelman #undef __FUNCT__ 142b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab" 1435c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 1443b3e256bSKris Buschelman { 145dfbe8321SBarry Smith PetscErrorCode ierr; 1463b3e256bSKris Buschelman 1473b3e256bSKris Buschelman PetscFunctionBegin; 148f0523c5fSHong Zhang if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 1497adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 150f0523c5fSHong Zhang ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 1517adad957SLisandro Dalcin ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 1523b3e256bSKris Buschelman ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 153b24902e0SBarry Smith (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 15435bd34faSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 155f0523c5fSHong Zhang 1565c9eb25fSBarry Smith (*F)->factor = MAT_FACTOR_LU; 1573b3e256bSKris Buschelman PetscFunctionReturn(0); 1583b3e256bSKris Buschelman } 1593b3e256bSKris Buschelman 160b24902e0SBarry Smith 1613b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/ 1623b3e256bSKris Buschelman #undef __FUNCT__ 16305db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab" 164156180f9SHong Zhang PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,const MatFactorInfo *info) 1653b3e256bSKris Buschelman { 166dfbe8321SBarry Smith PetscErrorCode ierr; 167de4209c5SBarry Smith size_t len; 1683b3e256bSKris Buschelman char *_A,*name; 169156180f9SHong Zhang PetscReal dt,dtcol; 170156180f9SHong Zhang Mat F; 1713b3e256bSKris Buschelman 1723b3e256bSKris Buschelman PetscFunctionBegin; 173156180f9SHong Zhang if (info->dt == PETSC_DEFAULT) dt = .005; 174156180f9SHong Zhang if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 175156180f9SHong Zhang ierr = MatGetFactor(A,MAT_SOLVER_MATLAB,MAT_FACTOR_ILU,&F);CHKERRQ(ierr); 176156180f9SHong Zhang F->ops->solve = MatSolve_Matlab; 177156180f9SHong Zhang F->factor = MAT_FACTOR_LU; 1787adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 179f0523c5fSHong Zhang _A = ((PetscObject)A)->name; 180156180f9SHong Zhang ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,dt,dtcol);CHKERRQ(ierr); 1817adad957SLisandro Dalcin 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); 1827adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 1833b3e256bSKris Buschelman 1843b3e256bSKris Buschelman ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 1853b3e256bSKris Buschelman ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 1863b3e256bSKris Buschelman sprintf(name,"_%s",_A); 187156180f9SHong Zhang ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 1883b3e256bSKris Buschelman ierr = PetscFree(name);CHKERRQ(ierr); 1893b3e256bSKris Buschelman PetscFunctionReturn(0); 1903b3e256bSKris Buschelman } 1913b3e256bSKris Buschelman 19205db81ecSKris Buschelman #undef __FUNCT__ 19305db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab" 194dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 1953b3e256bSKris Buschelman { 196dfbe8321SBarry Smith PetscErrorCode ierr; 1973b3e256bSKris Buschelman 1983b3e256bSKris Buschelman PetscFunctionBegin; 1993b3e256bSKris Buschelman ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 2003b3e256bSKris Buschelman PetscFunctionReturn(0); 2013b3e256bSKris Buschelman } 2023b3e256bSKris Buschelman 2033b3e256bSKris Buschelman #undef __FUNCT__ 20405db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab" 205b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 206b2d3331aSBarry Smith { 207dfbe8321SBarry Smith PetscErrorCode ierr; 20832077d6dSBarry Smith PetscTruth iascii; 20905db81ecSKris Buschelman PetscViewerFormat format; 21005db81ecSKris Buschelman 21105db81ecSKris Buschelman PetscFunctionBegin; 212b24902e0SBarry Smith ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 21332077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 21432077d6dSBarry Smith if (iascii) { 21505db81ecSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 21605db81ecSKris Buschelman if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 21705db81ecSKris Buschelman ierr = MatFactorInfo_Matlab(A,viewer); 21805db81ecSKris Buschelman } 21905db81ecSKris Buschelman } 22005db81ecSKris Buschelman PetscFunctionReturn(0); 22105db81ecSKris Buschelman } 222f365a357SKris Buschelman 22305db81ecSKris Buschelman 22405db81ecSKris Buschelman /*MC 22505db81ecSKris Buschelman MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance 22605db81ecSKris Buschelman based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 22705db81ecSKris Buschelman 22805db81ecSKris Buschelman If Matlab is instaled (see the manual for 22905db81ecSKris Buschelman instructions on how to declare the existence of external packages), 23005db81ecSKris Buschelman a matrix type can be constructed which invokes Matlab solvers. 23105db81ecSKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB). 23205db81ecSKris Buschelman This matrix type is only supported for double precision real. 23305db81ecSKris Buschelman 23405db81ecSKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 23505db81ecSKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 23605db81ecSKris Buschelman the MATSEQAIJ type without data copy. 23705db81ecSKris Buschelman 23805db81ecSKris Buschelman Options Database Keys: 23905db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions() 24005db81ecSKris Buschelman - -mat_matlab_qr - sets the direct solver to be QR instead of LU 24105db81ecSKris Buschelman 24205db81ecSKris Buschelman Level: beginner 24305db81ecSKris Buschelman 24405db81ecSKris Buschelman .seealso: PCLU 24505db81ecSKris Buschelman M*/ 24605db81ecSKris Buschelman 247