1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 33b3e256bSKris Buschelman /* 43b3e256bSKris Buschelman Provides an interface for the Matlab engine sparse solver 53b3e256bSKris Buschelman 63b3e256bSKris Buschelman */ 77c4f633dSBarry 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 12aeeaa5c7SBarry Smith EXTERN_C_BEGIN 13aeeaa5c7SBarry Smith #undef __FUNCT__ 14aeeaa5c7SBarry Smith #define __FUNCT__ "MatSeqAIJToMatlab" 15aeeaa5c7SBarry Smith mxArray *MatSeqAIJToMatlab(Mat B) 16aeeaa5c7SBarry Smith { 17aeeaa5c7SBarry Smith PetscErrorCode ierr; 18aeeaa5c7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 19aeeaa5c7SBarry Smith mwIndex i,*ii,*jj; 20aeeaa5c7SBarry Smith mxArray *mat; 21aeeaa5c7SBarry Smith 22aeeaa5c7SBarry Smith PetscFunctionBegin; 23aeeaa5c7SBarry Smith mat = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL); 24aeeaa5c7SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar)); 25aeeaa5c7SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 26aeeaa5c7SBarry Smith jj = mxGetIr(mat); 27aeeaa5c7SBarry Smith for (i=0; i<aij->nz; i++) jj[i] = aij->j[i]; 28aeeaa5c7SBarry Smith ii = mxGetJc(mat); 29aeeaa5c7SBarry Smith for (i=0; i<B->rmap->n+1; i++) ii[i] = aij->i[i]; 30aeeaa5c7SBarry Smith 31aeeaa5c7SBarry Smith PetscFunctionReturn(mat); 32aeeaa5c7SBarry Smith } 33aeeaa5c7SBarry Smith EXTERN_C_END 34aeeaa5c7SBarry Smith 35a1d52234SKris Buschelman 36a1d52234SKris Buschelman EXTERN_C_BEGIN 37a1d52234SKris Buschelman #undef __FUNCT__ 38b3866ffcSBarry Smith #define __FUNCT__ "MatlabEnginePut_SeqAIJ" 397087cfbeSBarry Smith PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 40a1d52234SKris Buschelman { 41dfbe8321SBarry Smith PetscErrorCode ierr; 42a1d52234SKris Buschelman mxArray *mat; 43a1d52234SKris Buschelman 44a1d52234SKris Buschelman PetscFunctionBegin; 45aeeaa5c7SBarry Smith mat = MatSeqAIJToMatlab((Mat)obj);CHKERRQ(ierr); 46a1d52234SKris Buschelman ierr = PetscObjectName(obj);CHKERRQ(ierr); 47a1d52234SKris Buschelman engPutVariable((Engine *)mengine,obj->name,mat); 48a1d52234SKris Buschelman PetscFunctionReturn(0); 49a1d52234SKris Buschelman } 50a1d52234SKris Buschelman EXTERN_C_END 51a1d52234SKris Buschelman 52a1d52234SKris Buschelman EXTERN_C_BEGIN 53a1d52234SKris Buschelman #undef __FUNCT__ 54a7bb0f05SBarry Smith #define __FUNCT__ "MatSeqAIJFromMatlab" 5584c105d7SBarry Smith /*@C 56a7bb0f05SBarry Smith MatSeqAIJFromMatlab - Given a Matlab sparse matrix, fills a SeqAIJ matrix with its transpose. 57a7bb0f05SBarry Smith 58a7bb0f05SBarry Smith Not Collective 59a7bb0f05SBarry Smith 60a7bb0f05SBarry Smith Input Parameters: 61a7bb0f05SBarry Smith + mmat - a Matlab sparse matris 62a7bb0f05SBarry Smith - mat - a already created MATSEQAIJ 63a7bb0f05SBarry Smith 64a7bb0f05SBarry Smith @*/ 657087cfbeSBarry Smith PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) 66a1d52234SKris Buschelman { 67dfbe8321SBarry Smith PetscErrorCode ierr; 68b3da158bSBarry Smith PetscInt nz,n,m,*i,*j,k; 69b3da158bSBarry Smith mwIndex nnz,nn,nm,*ii,*jj; 70a1d52234SKris Buschelman Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 71a1d52234SKris Buschelman 72a1d52234SKris Buschelman PetscFunctionBegin; 73b3da158bSBarry Smith nn = mxGetN(mmat); /* rows of transpose of matrix */ 74b3da158bSBarry Smith nm = mxGetM(mmat); 75b3da158bSBarry Smith nnz = (mxGetJc(mmat))[nn]; 76b3da158bSBarry Smith ii = mxGetJc(mmat); 77b3da158bSBarry Smith jj = mxGetIr(mmat); 78b3da158bSBarry Smith n = (PetscInt) nn; 79b3da158bSBarry Smith m = (PetscInt) nm; 80b3da158bSBarry Smith nz = (PetscInt) nnz; 81b3da158bSBarry Smith 82b3da158bSBarry Smith if (mat->rmap->n < 0 && mat->cmap->n < 0) { 83b3da158bSBarry Smith /* matrix has not yet had its size set */ 84b3da158bSBarry Smith ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 85b3da158bSBarry Smith ierr = MatPreallocated(mat);CHKERRQ(ierr); 86b3da158bSBarry Smith } else { 87b3da158bSBarry 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); 88b3da158bSBarry 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); 89b3da158bSBarry Smith } 90*2eff7a51SBarry Smith if (nz != aij->nz) { 91*2eff7a51SBarry Smith /* number of nonzeros in matrix has changed, so need new data structure */ 921f03425eSSatish Balay ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 93b3da158bSBarry Smith aij->nz = nz; 94f0523c5fSHong Zhang ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); 95a1d52234SKris Buschelman aij->singlemalloc = PETSC_TRUE; 96*2eff7a51SBarry Smith } 97a1d52234SKris Buschelman 98a1d52234SKris Buschelman ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 99a1d52234SKris Buschelman /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 100b3da158bSBarry Smith i = aij->i; 101b3da158bSBarry Smith for (k=0; k<n+1; k++) { 102b3da158bSBarry Smith i[k] = (PetscInt) ii[k]; 103b3da158bSBarry Smith } 104b3da158bSBarry Smith j = aij->j; 105b3da158bSBarry Smith for (k=0; k<nz; k++) { 106b3da158bSBarry Smith j[k] = (PetscInt) jj[k]; 107b3da158bSBarry Smith } 108a1d52234SKris Buschelman 109b3da158bSBarry Smith for (k=0; k<mat->rmap->n; k++) { 110b3da158bSBarry Smith aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; 111a1d52234SKris Buschelman } 112a1d52234SKris Buschelman 113a1d52234SKris Buschelman ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 114a1d52234SKris Buschelman ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 115a7bb0f05SBarry Smith PetscFunctionReturn(0); 116a7bb0f05SBarry Smith } 117a7bb0f05SBarry Smith EXTERN_C_END 118a1d52234SKris Buschelman 119a7bb0f05SBarry Smith 120a7bb0f05SBarry Smith EXTERN_C_BEGIN 121a7bb0f05SBarry Smith #undef __FUNCT__ 122a7bb0f05SBarry Smith #define __FUNCT__ "MatlabEngineGet_SeqAIJ" 1237087cfbeSBarry Smith PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 124a7bb0f05SBarry Smith { 125a7bb0f05SBarry Smith PetscErrorCode ierr; 126a7bb0f05SBarry Smith Mat mat = (Mat)obj; 127a7bb0f05SBarry Smith mxArray *mmat; 128a7bb0f05SBarry Smith 129a7bb0f05SBarry Smith PetscFunctionBegin; 130a7bb0f05SBarry Smith mmat = engGetVariable((Engine *)mengine,obj->name); 131a7bb0f05SBarry Smith ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr); 132a1d52234SKris Buschelman PetscFunctionReturn(0); 133a1d52234SKris Buschelman } 134a1d52234SKris Buschelman EXTERN_C_END 135a1d52234SKris Buschelman 13605db81ecSKris Buschelman #undef __FUNCT__ 13705db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab" 138dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 1393b3e256bSKris Buschelman { 140dfbe8321SBarry Smith PetscErrorCode ierr; 141e060cb09SBarry Smith const char *_A,*_b,*_x; 1423b3e256bSKris Buschelman 1433b3e256bSKris Buschelman PetscFunctionBegin; 1443b3e256bSKris Buschelman /* make sure objects have names; use default if not */ 1453b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 1463b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 1473b3e256bSKris Buschelman 1483b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 1493b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 1503b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 1517adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 1527adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 1537adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 1547adad957SLisandro Dalcin /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 1557adad957SLisandro Dalcin ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 1563b3e256bSKris Buschelman PetscFunctionReturn(0); 1573b3e256bSKris Buschelman } 1583b3e256bSKris Buschelman 1593b3e256bSKris Buschelman #undef __FUNCT__ 16005db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab" 1610481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 1623b3e256bSKris Buschelman { 163dfbe8321SBarry Smith PetscErrorCode ierr; 164de4209c5SBarry Smith size_t len; 1653b3e256bSKris Buschelman char *_A,*name; 166b3866ffcSBarry Smith PetscReal dtcol = info->dtcol; 1673b3e256bSKris Buschelman 1683b3e256bSKris Buschelman PetscFunctionBegin; 169d5f3da31SBarry Smith if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) { 170b3866ffcSBarry Smith if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 171fe97e370SBarry Smith F->ops->solve = MatSolve_Matlab; 172d5f3da31SBarry Smith F->factortype = MAT_FACTOR_LU; 173fe97e370SBarry Smith ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 174fe97e370SBarry Smith _A = ((PetscObject)A)->name; 175b3866ffcSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr); 176fe97e370SBarry Smith 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); 177fe97e370SBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 178fe97e370SBarry Smith 179fe97e370SBarry Smith ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 180fe97e370SBarry Smith ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 181fe97e370SBarry Smith sprintf(name,"_%s",_A); 182fe97e370SBarry Smith ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 183fe97e370SBarry Smith ierr = PetscFree(name);CHKERRQ(ierr); 184fe97e370SBarry Smith } else { 1857adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 186f0523c5fSHong Zhang _A = ((PetscObject)A)->name; 187b3866ffcSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);CHKERRQ(ierr); 1887adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 1893b3e256bSKris Buschelman ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 1903b3e256bSKris Buschelman ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 1913b3e256bSKris Buschelman sprintf(name,"_%s",_A); 192f0523c5fSHong Zhang ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 1933b3e256bSKris Buschelman ierr = PetscFree(name);CHKERRQ(ierr); 194f0523c5fSHong Zhang F->ops->solve = MatSolve_Matlab; 195fe97e370SBarry Smith } 1963b3e256bSKris Buschelman PetscFunctionReturn(0); 1973b3e256bSKris Buschelman } 1983b3e256bSKris Buschelman 1993b3e256bSKris Buschelman #undef __FUNCT__ 20005db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 2010481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 2023b3e256bSKris Buschelman { 2033b3e256bSKris Buschelman PetscFunctionBegin; 204e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 205f0523c5fSHong Zhang F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 206b3866ffcSBarry Smith F->assembled = PETSC_TRUE; 2073b3e256bSKris Buschelman PetscFunctionReturn(0); 2083b3e256bSKris Buschelman } 2093b3e256bSKris Buschelman 21035bd34faSBarry Smith EXTERN_C_BEGIN 21135bd34faSBarry Smith #undef __FUNCT__ 21235bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 21335bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 21435bd34faSBarry Smith { 21535bd34faSBarry Smith PetscFunctionBegin; 2162692d6eeSBarry Smith *type = MATSOLVERMATLAB; 21735bd34faSBarry Smith PetscFunctionReturn(0); 21835bd34faSBarry Smith } 21935bd34faSBarry Smith EXTERN_C_END 22035bd34faSBarry Smith 2213b3e256bSKris Buschelman #undef __FUNCT__ 222b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab" 2235c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 2243b3e256bSKris Buschelman { 225dfbe8321SBarry Smith PetscErrorCode ierr; 2263b3e256bSKris Buschelman 2273b3e256bSKris Buschelman PetscFunctionBegin; 228e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 2297adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 230f0523c5fSHong Zhang ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 2317adad957SLisandro Dalcin ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 2323b3e256bSKris Buschelman ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 233b24902e0SBarry Smith (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 234b3866ffcSBarry Smith (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab; 235f75d6de4SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 236f0523c5fSHong Zhang 237d5f3da31SBarry Smith (*F)->factortype = ftype; 2383b3e256bSKris Buschelman PetscFunctionReturn(0); 2393b3e256bSKris Buschelman } 2403b3e256bSKris Buschelman 241b24902e0SBarry Smith 2423b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/ 2433b3e256bSKris Buschelman 24405db81ecSKris Buschelman #undef __FUNCT__ 24505db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab" 246dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 2473b3e256bSKris Buschelman { 248dfbe8321SBarry Smith PetscErrorCode ierr; 2493b3e256bSKris Buschelman 2503b3e256bSKris Buschelman PetscFunctionBegin; 2513b3e256bSKris Buschelman ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 2523b3e256bSKris Buschelman PetscFunctionReturn(0); 2533b3e256bSKris Buschelman } 2543b3e256bSKris Buschelman 2553b3e256bSKris Buschelman #undef __FUNCT__ 25605db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab" 257b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 258b2d3331aSBarry Smith { 259dfbe8321SBarry Smith PetscErrorCode ierr; 260ace3abfcSBarry Smith PetscBool iascii; 26105db81ecSKris Buschelman PetscViewerFormat format; 26205db81ecSKris Buschelman 26305db81ecSKris Buschelman PetscFunctionBegin; 264b24902e0SBarry Smith ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 2652692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 26632077d6dSBarry Smith if (iascii) { 26705db81ecSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 26805db81ecSKris Buschelman if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 26905db81ecSKris Buschelman ierr = MatFactorInfo_Matlab(A,viewer); 27005db81ecSKris Buschelman } 27105db81ecSKris Buschelman } 27205db81ecSKris Buschelman PetscFunctionReturn(0); 27305db81ecSKris Buschelman } 274f365a357SKris Buschelman 27505db81ecSKris Buschelman 27605db81ecSKris Buschelman /*MC 2772692d6eeSBarry Smith MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance 27805db81ecSKris Buschelman based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 27905db81ecSKris Buschelman 28005db81ecSKris Buschelman 28141c8de11SBarry Smith Works with MATSEQAIJ matrices. 28205db81ecSKris Buschelman 28305db81ecSKris Buschelman Options Database Keys: 28441c8de11SBarry Smith . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization 28541c8de11SBarry Smith 28605db81ecSKris Buschelman 28705db81ecSKris Buschelman Level: beginner 28805db81ecSKris Buschelman 28905db81ecSKris Buschelman .seealso: PCLU 29041c8de11SBarry Smith 29141c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 29205db81ecSKris Buschelman M*/ 29305db81ecSKris Buschelman 294