1be1d678aSKris Buschelman 23b3e256bSKris Buschelman /* 3e3c5b3baSBarry Smith Provides an interface for the MATLAB engine sparse solver 43b3e256bSKris Buschelman 53b3e256bSKris Buschelman */ 6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 782c86c8fSBarry Smith #include <petscmatlab.h> 8c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 9c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 103b3e256bSKris Buschelman 11aeeaa5c7SBarry Smith #undef __FUNCT__ 12aeeaa5c7SBarry Smith #define __FUNCT__ "MatSeqAIJToMatlab" 138cc058d9SJed Brown PETSC_EXTERN mxArray *MatSeqAIJToMatlab(Mat B) 14aeeaa5c7SBarry Smith { 15aeeaa5c7SBarry Smith PetscErrorCode ierr; 16aeeaa5c7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 17c088a8dcSBarry Smith mwIndex *ii,*jj; 18aeeaa5c7SBarry Smith mxArray *mat; 19c088a8dcSBarry Smith PetscInt i; 20aeeaa5c7SBarry Smith 21aeeaa5c7SBarry Smith PetscFunctionBegin; 22aeeaa5c7SBarry Smith mat = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL); 23a3afe2d1SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 24e3c5b3baSBarry Smith /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ 25aeeaa5c7SBarry Smith jj = mxGetIr(mat); 26aeeaa5c7SBarry Smith for (i=0; i<aij->nz; i++) jj[i] = aij->j[i]; 27aeeaa5c7SBarry Smith ii = mxGetJc(mat); 28aeeaa5c7SBarry Smith for (i=0; i<B->rmap->n+1; i++) ii[i] = aij->i[i]; 29aeeaa5c7SBarry Smith PetscFunctionReturn(mat); 30aeeaa5c7SBarry Smith } 31aeeaa5c7SBarry Smith 32a1d52234SKris Buschelman #undef __FUNCT__ 33b3866ffcSBarry Smith #define __FUNCT__ "MatlabEnginePut_SeqAIJ" 348cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 35a1d52234SKris Buschelman { 36dfbe8321SBarry Smith PetscErrorCode ierr; 37a1d52234SKris Buschelman mxArray *mat; 38a1d52234SKris Buschelman 39a1d52234SKris Buschelman PetscFunctionBegin; 40be6adb11SBarry Smith mat = MatSeqAIJToMatlab((Mat)obj);if (!mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot create MATLAB matrix"); 41a1d52234SKris Buschelman ierr = PetscObjectName(obj);CHKERRQ(ierr); 42a1d52234SKris Buschelman engPutVariable((Engine*)mengine,obj->name,mat); 43a1d52234SKris Buschelman PetscFunctionReturn(0); 44a1d52234SKris Buschelman } 45a1d52234SKris Buschelman 46a1d52234SKris Buschelman #undef __FUNCT__ 47a7bb0f05SBarry Smith #define __FUNCT__ "MatSeqAIJFromMatlab" 4884c105d7SBarry Smith /*@C 49e3c5b3baSBarry Smith MatSeqAIJFromMatlab - Given a MATLAB sparse matrix, fills a SeqAIJ matrix with its transpose. 50a7bb0f05SBarry Smith 51a7bb0f05SBarry Smith Not Collective 52a7bb0f05SBarry Smith 53a7bb0f05SBarry Smith Input Parameters: 54e3c5b3baSBarry Smith + mmat - a MATLAB sparse matris 55a7bb0f05SBarry Smith - mat - a already created MATSEQAIJ 56a7bb0f05SBarry Smith 572bd2b0e6SSatish Balay Level: intermediate 582bd2b0e6SSatish Balay 59a7bb0f05SBarry Smith @*/ 608cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) 61a1d52234SKris Buschelman { 62dfbe8321SBarry Smith PetscErrorCode ierr; 63b3da158bSBarry Smith PetscInt nz,n,m,*i,*j,k; 64b3da158bSBarry Smith mwIndex nnz,nn,nm,*ii,*jj; 65a1d52234SKris Buschelman Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 66a1d52234SKris Buschelman 67a1d52234SKris Buschelman PetscFunctionBegin; 68b3da158bSBarry Smith nn = mxGetN(mmat); /* rows of transpose of matrix */ 69b3da158bSBarry Smith nm = mxGetM(mmat); 70b3da158bSBarry Smith nnz = (mxGetJc(mmat))[nn]; 71b3da158bSBarry Smith ii = mxGetJc(mmat); 72b3da158bSBarry Smith jj = mxGetIr(mmat); 73b3da158bSBarry Smith n = (PetscInt) nn; 74b3da158bSBarry Smith m = (PetscInt) nm; 75b3da158bSBarry Smith nz = (PetscInt) nnz; 76b3da158bSBarry Smith 77b3da158bSBarry Smith if (mat->rmap->n < 0 && mat->cmap->n < 0) { 78b3da158bSBarry Smith /* matrix has not yet had its size set */ 79b3da158bSBarry Smith ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 804994cf47SJed Brown ierr = MatSetUp(mat);CHKERRQ(ierr); 81b3da158bSBarry Smith } else { 82b3da158bSBarry Smith if (mat->rmap->n != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->rmap->n,n); 83b3da158bSBarry Smith if (mat->cmap->n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change size of PETSc matrix %D to %D",mat->cmap->n,m); 84b3da158bSBarry Smith } 852eff7a51SBarry Smith if (nz != aij->nz) { 862eff7a51SBarry Smith /* number of nonzeros in matrix has changed, so need new data structure */ 871f03425eSSatish Balay ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 88b3da158bSBarry Smith aij->nz = nz; 89*dcca6d9dSJed Brown ierr = PetscMalloc3(aij->nz,&aij->a,aij->nz,&aij->j,mat->rmap->n+1,&aij->i);CHKERRQ(ierr); 902205254eSKarl Rupp 91a1d52234SKris Buschelman aij->singlemalloc = PETSC_TRUE; 922eff7a51SBarry Smith } 93a1d52234SKris Buschelman 94a1d52234SKris Buschelman ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 95e3c5b3baSBarry Smith /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ 96b3da158bSBarry Smith i = aij->i; 972205254eSKarl Rupp for (k=0; k<n+1; k++) i[k] = (PetscInt) ii[k]; 98b3da158bSBarry Smith j = aij->j; 992205254eSKarl Rupp for (k=0; k<nz; k++) j[k] = (PetscInt) jj[k]; 100a1d52234SKris Buschelman 1012205254eSKarl Rupp for (k=0; k<mat->rmap->n; k++) aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; 102a1d52234SKris Buschelman 103a1d52234SKris Buschelman ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 104a1d52234SKris Buschelman ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 105a7bb0f05SBarry Smith PetscFunctionReturn(0); 106a7bb0f05SBarry Smith } 107a1d52234SKris Buschelman 108a7bb0f05SBarry Smith #undef __FUNCT__ 109a7bb0f05SBarry Smith #define __FUNCT__ "MatlabEngineGet_SeqAIJ" 1107087cfbeSBarry Smith PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 111a7bb0f05SBarry Smith { 112a7bb0f05SBarry Smith PetscErrorCode ierr; 113a7bb0f05SBarry Smith Mat mat = (Mat)obj; 114a7bb0f05SBarry Smith mxArray *mmat; 115a7bb0f05SBarry Smith 116a7bb0f05SBarry Smith PetscFunctionBegin; 117a7bb0f05SBarry Smith mmat = engGetVariable((Engine*)mengine,obj->name); 118a7bb0f05SBarry Smith ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr); 119a1d52234SKris Buschelman PetscFunctionReturn(0); 120a1d52234SKris Buschelman } 121a1d52234SKris Buschelman 12205db81ecSKris Buschelman #undef __FUNCT__ 12305db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab" 124dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 1253b3e256bSKris Buschelman { 126dfbe8321SBarry Smith PetscErrorCode ierr; 127e060cb09SBarry Smith const char *_A,*_b,*_x; 1283b3e256bSKris Buschelman 1293b3e256bSKris Buschelman PetscFunctionBegin; 1303b3e256bSKris Buschelman /* make sure objects have names; use default if not */ 1313b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 1323b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 1333b3e256bSKris Buschelman 1343b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 1353b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 1363b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 137ce94432eSBarry Smith ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),(PetscObject)b);CHKERRQ(ierr); 138ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 139ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"%s = 0;",_b);CHKERRQ(ierr); 140ce94432eSBarry Smith /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),stdout);CHKERRQ(ierr); */ 141ce94432eSBarry Smith ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),(PetscObject)x);CHKERRQ(ierr); 1423b3e256bSKris Buschelman PetscFunctionReturn(0); 1433b3e256bSKris Buschelman } 1443b3e256bSKris Buschelman 1453b3e256bSKris Buschelman #undef __FUNCT__ 14605db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab" 1470481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 1483b3e256bSKris Buschelman { 149dfbe8321SBarry Smith PetscErrorCode ierr; 150de4209c5SBarry Smith size_t len; 1513b3e256bSKris Buschelman char *_A,*name; 152b3866ffcSBarry Smith PetscReal dtcol = info->dtcol; 1533b3e256bSKris Buschelman 1543b3e256bSKris Buschelman PetscFunctionBegin; 155d5f3da31SBarry Smith if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) { 156b3866ffcSBarry Smith if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 157fe97e370SBarry Smith F->ops->solve = MatSolve_Matlab; 158d5f3da31SBarry Smith F->factortype = MAT_FACTOR_LU; 1592205254eSKarl Rupp 160ce94432eSBarry Smith ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),(PetscObject)A);CHKERRQ(ierr); 161fe97e370SBarry Smith _A = ((PetscObject)A)->name; 162ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr); 163ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr); 164ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"%s = 0;",_A);CHKERRQ(ierr); 165fe97e370SBarry Smith 166fe97e370SBarry Smith ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 167fe97e370SBarry Smith ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 168fe97e370SBarry Smith sprintf(name,"_%s",_A); 169fe97e370SBarry Smith ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 170fe97e370SBarry Smith ierr = PetscFree(name);CHKERRQ(ierr); 171fe97e370SBarry Smith } else { 172ce94432eSBarry Smith ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),(PetscObject)A);CHKERRQ(ierr); 173f0523c5fSHong Zhang _A = ((PetscObject)A)->name; 174ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);CHKERRQ(ierr); 175ce94432eSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(PetscObjectComm((PetscObject)A)),"%s = 0;",_A);CHKERRQ(ierr); 1763b3e256bSKris Buschelman ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 1773b3e256bSKris Buschelman ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 1783b3e256bSKris Buschelman sprintf(name,"_%s",_A); 179f0523c5fSHong Zhang ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 1803b3e256bSKris Buschelman ierr = PetscFree(name);CHKERRQ(ierr); 1812205254eSKarl Rupp 182f0523c5fSHong Zhang F->ops->solve = MatSolve_Matlab; 183fe97e370SBarry Smith } 1843b3e256bSKris Buschelman PetscFunctionReturn(0); 1853b3e256bSKris Buschelman } 1863b3e256bSKris Buschelman 1873b3e256bSKris Buschelman #undef __FUNCT__ 18805db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 1890481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 1903b3e256bSKris Buschelman { 1913b3e256bSKris Buschelman PetscFunctionBegin; 192e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 193f0523c5fSHong Zhang F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 194b3866ffcSBarry Smith F->assembled = PETSC_TRUE; 1953b3e256bSKris Buschelman PetscFunctionReturn(0); 1963b3e256bSKris Buschelman } 1973b3e256bSKris Buschelman 19835bd34faSBarry Smith #undef __FUNCT__ 19935bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 20035bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 20135bd34faSBarry Smith { 20235bd34faSBarry Smith PetscFunctionBegin; 2032692d6eeSBarry Smith *type = MATSOLVERMATLAB; 20435bd34faSBarry Smith PetscFunctionReturn(0); 20535bd34faSBarry Smith } 20635bd34faSBarry Smith 2073b3e256bSKris Buschelman #undef __FUNCT__ 208b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab" 2098cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 2103b3e256bSKris Buschelman { 211dfbe8321SBarry Smith PetscErrorCode ierr; 2123b3e256bSKris Buschelman 2133b3e256bSKris Buschelman PetscFunctionBegin; 214e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 215ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),F);CHKERRQ(ierr); 216f0523c5fSHong Zhang ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 2177adad957SLisandro Dalcin ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 2180298fd71SBarry Smith ierr = MatSeqAIJSetPreallocation(*F,0,NULL);CHKERRQ(ierr); 219b24902e0SBarry Smith (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 220b3866ffcSBarry Smith (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab; 2212205254eSKarl Rupp 222bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)(*F),"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 223f0523c5fSHong Zhang 224d5f3da31SBarry Smith (*F)->factortype = ftype; 2253b3e256bSKris Buschelman PetscFunctionReturn(0); 2263b3e256bSKris Buschelman } 227b24902e0SBarry Smith 2283b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/ 2293b3e256bSKris Buschelman 23005db81ecSKris Buschelman #undef __FUNCT__ 23105db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab" 232dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 2333b3e256bSKris Buschelman { 234dfbe8321SBarry Smith PetscErrorCode ierr; 2353b3e256bSKris Buschelman 2363b3e256bSKris Buschelman PetscFunctionBegin; 237e3c5b3baSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"MATLAB run parameters: -- not written yet!\n");CHKERRQ(ierr); 2383b3e256bSKris Buschelman PetscFunctionReturn(0); 2393b3e256bSKris Buschelman } 2403b3e256bSKris Buschelman 2413b3e256bSKris Buschelman #undef __FUNCT__ 24205db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab" 243b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 244b2d3331aSBarry Smith { 245dfbe8321SBarry Smith PetscErrorCode ierr; 246ace3abfcSBarry Smith PetscBool iascii; 24705db81ecSKris Buschelman PetscViewerFormat format; 24805db81ecSKris Buschelman 24905db81ecSKris Buschelman PetscFunctionBegin; 250b24902e0SBarry Smith ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 251251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 25232077d6dSBarry Smith if (iascii) { 25305db81ecSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 25405db81ecSKris Buschelman if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 25505db81ecSKris Buschelman ierr = MatFactorInfo_Matlab(A,viewer); 25605db81ecSKris Buschelman } 25705db81ecSKris Buschelman } 25805db81ecSKris Buschelman PetscFunctionReturn(0); 25905db81ecSKris Buschelman } 260f365a357SKris Buschelman 26105db81ecSKris Buschelman 26205db81ecSKris Buschelman /*MC 2632692d6eeSBarry Smith MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance 264e3c5b3baSBarry Smith based ILU factorization (ILUDT) for sequential matrices via the external package MATLAB. 26505db81ecSKris Buschelman 26605db81ecSKris Buschelman 26741c8de11SBarry Smith Works with MATSEQAIJ matrices. 26805db81ecSKris Buschelman 26905db81ecSKris Buschelman Options Database Keys: 270e3c5b3baSBarry Smith . -pc_factor_mat_solver_type matlab - selects MATLAB to do the sparse factorization 27141c8de11SBarry Smith 27205db81ecSKris Buschelman 27305db81ecSKris Buschelman Level: beginner 27405db81ecSKris Buschelman 27505db81ecSKris Buschelman .seealso: PCLU 27641c8de11SBarry Smith 27741c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 27805db81ecSKris Buschelman M*/ 27905db81ecSKris Buschelman 280