1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 33b3e256bSKris Buschelman /* 4e3c5b3baSBarry Smith 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 9e3c5b3baSBarry Smith #include "engine.h" /* MATLAB include file */ 10e3c5b3baSBarry Smith #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; 19*c088a8dcSBarry Smith mwIndex *ii,*jj; 20aeeaa5c7SBarry Smith mxArray *mat; 21*c088a8dcSBarry Smith PetscInt i; 22aeeaa5c7SBarry Smith 23aeeaa5c7SBarry Smith PetscFunctionBegin; 24aeeaa5c7SBarry Smith mat = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL); 25aeeaa5c7SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar)); 26e3c5b3baSBarry Smith /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ 27aeeaa5c7SBarry Smith jj = mxGetIr(mat); 28aeeaa5c7SBarry Smith for (i=0; i<aij->nz; i++) jj[i] = aij->j[i]; 29aeeaa5c7SBarry Smith ii = mxGetJc(mat); 30aeeaa5c7SBarry Smith for (i=0; i<B->rmap->n+1; i++) ii[i] = aij->i[i]; 31aeeaa5c7SBarry Smith 32aeeaa5c7SBarry Smith PetscFunctionReturn(mat); 33aeeaa5c7SBarry Smith } 34aeeaa5c7SBarry Smith EXTERN_C_END 35aeeaa5c7SBarry Smith 36a1d52234SKris Buschelman 37a1d52234SKris Buschelman EXTERN_C_BEGIN 38a1d52234SKris Buschelman #undef __FUNCT__ 39b3866ffcSBarry Smith #define __FUNCT__ "MatlabEnginePut_SeqAIJ" 407087cfbeSBarry Smith PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 41a1d52234SKris Buschelman { 42dfbe8321SBarry Smith PetscErrorCode ierr; 43a1d52234SKris Buschelman mxArray *mat; 44a1d52234SKris Buschelman 45a1d52234SKris Buschelman PetscFunctionBegin; 46be6adb11SBarry Smith mat = MatSeqAIJToMatlab((Mat)obj);if (!mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot create MATLAB matrix"); 47a1d52234SKris Buschelman ierr = PetscObjectName(obj);CHKERRQ(ierr); 48a1d52234SKris Buschelman engPutVariable((Engine *)mengine,obj->name,mat); 49a1d52234SKris Buschelman PetscFunctionReturn(0); 50a1d52234SKris Buschelman } 51a1d52234SKris Buschelman EXTERN_C_END 52a1d52234SKris Buschelman 53a1d52234SKris Buschelman EXTERN_C_BEGIN 54a1d52234SKris Buschelman #undef __FUNCT__ 55a7bb0f05SBarry Smith #define __FUNCT__ "MatSeqAIJFromMatlab" 5684c105d7SBarry Smith /*@C 57e3c5b3baSBarry Smith MatSeqAIJFromMatlab - Given a MATLAB sparse matrix, fills a SeqAIJ matrix with its transpose. 58a7bb0f05SBarry Smith 59a7bb0f05SBarry Smith Not Collective 60a7bb0f05SBarry Smith 61a7bb0f05SBarry Smith Input Parameters: 62e3c5b3baSBarry Smith + mmat - a MATLAB sparse matris 63a7bb0f05SBarry Smith - mat - a already created MATSEQAIJ 64a7bb0f05SBarry Smith 65a7bb0f05SBarry Smith @*/ 667087cfbeSBarry Smith PetscErrorCode MatSeqAIJFromMatlab(mxArray *mmat,Mat mat) 67a1d52234SKris Buschelman { 68dfbe8321SBarry Smith PetscErrorCode ierr; 69b3da158bSBarry Smith PetscInt nz,n,m,*i,*j,k; 70b3da158bSBarry Smith mwIndex nnz,nn,nm,*ii,*jj; 71a1d52234SKris Buschelman Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 72a1d52234SKris Buschelman 73a1d52234SKris Buschelman PetscFunctionBegin; 74b3da158bSBarry Smith nn = mxGetN(mmat); /* rows of transpose of matrix */ 75b3da158bSBarry Smith nm = mxGetM(mmat); 76b3da158bSBarry Smith nnz = (mxGetJc(mmat))[nn]; 77b3da158bSBarry Smith ii = mxGetJc(mmat); 78b3da158bSBarry Smith jj = mxGetIr(mmat); 79b3da158bSBarry Smith n = (PetscInt) nn; 80b3da158bSBarry Smith m = (PetscInt) nm; 81b3da158bSBarry Smith nz = (PetscInt) nnz; 82b3da158bSBarry Smith 83b3da158bSBarry Smith if (mat->rmap->n < 0 && mat->cmap->n < 0) { 84b3da158bSBarry Smith /* matrix has not yet had its size set */ 85b3da158bSBarry Smith ierr = MatSetSizes(mat,n,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 86b3da158bSBarry Smith ierr = MatPreallocated(mat);CHKERRQ(ierr); 87b3da158bSBarry Smith } else { 88b3da158bSBarry 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); 89b3da158bSBarry 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); 90b3da158bSBarry Smith } 912eff7a51SBarry Smith if (nz != aij->nz) { 922eff7a51SBarry Smith /* number of nonzeros in matrix has changed, so need new data structure */ 931f03425eSSatish Balay ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 94b3da158bSBarry Smith aij->nz = nz; 95f0523c5fSHong Zhang ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr); 96a1d52234SKris Buschelman aij->singlemalloc = PETSC_TRUE; 972eff7a51SBarry Smith } 98a1d52234SKris Buschelman 99a1d52234SKris Buschelman ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 100e3c5b3baSBarry Smith /* MATLAB stores by column, not row so we pass in the transpose of the matrix */ 101b3da158bSBarry Smith i = aij->i; 102b3da158bSBarry Smith for (k=0; k<n+1; k++) { 103b3da158bSBarry Smith i[k] = (PetscInt) ii[k]; 104b3da158bSBarry Smith } 105b3da158bSBarry Smith j = aij->j; 106b3da158bSBarry Smith for (k=0; k<nz; k++) { 107b3da158bSBarry Smith j[k] = (PetscInt) jj[k]; 108b3da158bSBarry Smith } 109a1d52234SKris Buschelman 110b3da158bSBarry Smith for (k=0; k<mat->rmap->n; k++) { 111b3da158bSBarry Smith aij->ilen[k] = aij->imax[k] = aij->i[k+1] - aij->i[k]; 112a1d52234SKris Buschelman } 113a1d52234SKris Buschelman 114a1d52234SKris Buschelman ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 115a1d52234SKris Buschelman ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 116a7bb0f05SBarry Smith PetscFunctionReturn(0); 117a7bb0f05SBarry Smith } 118a7bb0f05SBarry Smith EXTERN_C_END 119a1d52234SKris Buschelman 120a7bb0f05SBarry Smith 121a7bb0f05SBarry Smith EXTERN_C_BEGIN 122a7bb0f05SBarry Smith #undef __FUNCT__ 123a7bb0f05SBarry Smith #define __FUNCT__ "MatlabEngineGet_SeqAIJ" 1247087cfbeSBarry Smith PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 125a7bb0f05SBarry Smith { 126a7bb0f05SBarry Smith PetscErrorCode ierr; 127a7bb0f05SBarry Smith Mat mat = (Mat)obj; 128a7bb0f05SBarry Smith mxArray *mmat; 129a7bb0f05SBarry Smith 130a7bb0f05SBarry Smith PetscFunctionBegin; 131a7bb0f05SBarry Smith mmat = engGetVariable((Engine *)mengine,obj->name); 132a7bb0f05SBarry Smith ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr); 133a1d52234SKris Buschelman PetscFunctionReturn(0); 134a1d52234SKris Buschelman } 135a1d52234SKris Buschelman EXTERN_C_END 136a1d52234SKris Buschelman 13705db81ecSKris Buschelman #undef __FUNCT__ 13805db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab" 139dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 1403b3e256bSKris Buschelman { 141dfbe8321SBarry Smith PetscErrorCode ierr; 142e060cb09SBarry Smith const char *_A,*_b,*_x; 1433b3e256bSKris Buschelman 1443b3e256bSKris Buschelman PetscFunctionBegin; 1453b3e256bSKris Buschelman /* make sure objects have names; use default if not */ 1463b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 1473b3e256bSKris Buschelman ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 1483b3e256bSKris Buschelman 1493b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 1503b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 1513b3e256bSKris Buschelman ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 1527adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr); 1537adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 1547adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr); 1557adad957SLisandro Dalcin /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr); */ 1567adad957SLisandro Dalcin ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr); 1573b3e256bSKris Buschelman PetscFunctionReturn(0); 1583b3e256bSKris Buschelman } 1593b3e256bSKris Buschelman 1603b3e256bSKris Buschelman #undef __FUNCT__ 16105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab" 1620481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info) 1633b3e256bSKris Buschelman { 164dfbe8321SBarry Smith PetscErrorCode ierr; 165de4209c5SBarry Smith size_t len; 1663b3e256bSKris Buschelman char *_A,*name; 167b3866ffcSBarry Smith PetscReal dtcol = info->dtcol; 1683b3e256bSKris Buschelman 1693b3e256bSKris Buschelman PetscFunctionBegin; 170d5f3da31SBarry Smith if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) { 171b3866ffcSBarry Smith if (info->dtcol == PETSC_DEFAULT) dtcol = .01; 172fe97e370SBarry Smith F->ops->solve = MatSolve_Matlab; 173d5f3da31SBarry Smith F->factortype = MAT_FACTOR_LU; 174fe97e370SBarry Smith ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 175fe97e370SBarry Smith _A = ((PetscObject)A)->name; 176b3866ffcSBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr); 177fe97e370SBarry 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); 178fe97e370SBarry Smith ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 179fe97e370SBarry Smith 180fe97e370SBarry Smith ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 181fe97e370SBarry Smith ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 182fe97e370SBarry Smith sprintf(name,"_%s",_A); 183fe97e370SBarry Smith ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 184fe97e370SBarry Smith ierr = PetscFree(name);CHKERRQ(ierr); 185fe97e370SBarry Smith } else { 1867adad957SLisandro Dalcin ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr); 187f0523c5fSHong Zhang _A = ((PetscObject)A)->name; 188b3866ffcSBarry 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); 1897adad957SLisandro Dalcin ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr); 1903b3e256bSKris Buschelman ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 1913b3e256bSKris Buschelman ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 1923b3e256bSKris Buschelman sprintf(name,"_%s",_A); 193f0523c5fSHong Zhang ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr); 1943b3e256bSKris Buschelman ierr = PetscFree(name);CHKERRQ(ierr); 195f0523c5fSHong Zhang F->ops->solve = MatSolve_Matlab; 196fe97e370SBarry Smith } 1973b3e256bSKris Buschelman PetscFunctionReturn(0); 1983b3e256bSKris Buschelman } 1993b3e256bSKris Buschelman 2003b3e256bSKris Buschelman #undef __FUNCT__ 20105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 2020481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 2033b3e256bSKris Buschelman { 2043b3e256bSKris Buschelman PetscFunctionBegin; 205e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 206f0523c5fSHong Zhang F->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 207b3866ffcSBarry Smith F->assembled = PETSC_TRUE; 2083b3e256bSKris Buschelman PetscFunctionReturn(0); 2093b3e256bSKris Buschelman } 2103b3e256bSKris Buschelman 21135bd34faSBarry Smith EXTERN_C_BEGIN 21235bd34faSBarry Smith #undef __FUNCT__ 21335bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab" 21435bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type) 21535bd34faSBarry Smith { 21635bd34faSBarry Smith PetscFunctionBegin; 2172692d6eeSBarry Smith *type = MATSOLVERMATLAB; 21835bd34faSBarry Smith PetscFunctionReturn(0); 21935bd34faSBarry Smith } 22035bd34faSBarry Smith EXTERN_C_END 22135bd34faSBarry Smith 2223b3e256bSKris Buschelman #undef __FUNCT__ 223b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab" 2245c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F) 2253b3e256bSKris Buschelman { 226dfbe8321SBarry Smith PetscErrorCode ierr; 2273b3e256bSKris Buschelman 2283b3e256bSKris Buschelman PetscFunctionBegin; 229e32f2f54SBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 2307adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr); 231f0523c5fSHong Zhang ierr = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 2327adad957SLisandro Dalcin ierr = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr); 2333b3e256bSKris Buschelman ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 234b24902e0SBarry Smith (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 235b3866ffcSBarry Smith (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab; 236f75d6de4SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr); 237f0523c5fSHong Zhang 238d5f3da31SBarry Smith (*F)->factortype = ftype; 2393b3e256bSKris Buschelman PetscFunctionReturn(0); 2403b3e256bSKris Buschelman } 2413b3e256bSKris Buschelman 242b24902e0SBarry Smith 2433b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/ 2443b3e256bSKris Buschelman 24505db81ecSKris Buschelman #undef __FUNCT__ 24605db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab" 247dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 2483b3e256bSKris Buschelman { 249dfbe8321SBarry Smith PetscErrorCode ierr; 2503b3e256bSKris Buschelman 2513b3e256bSKris Buschelman PetscFunctionBegin; 252e3c5b3baSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"MATLAB run parameters: -- not written yet!\n");CHKERRQ(ierr); 2533b3e256bSKris Buschelman PetscFunctionReturn(0); 2543b3e256bSKris Buschelman } 2553b3e256bSKris Buschelman 2563b3e256bSKris Buschelman #undef __FUNCT__ 25705db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab" 258b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 259b2d3331aSBarry Smith { 260dfbe8321SBarry Smith PetscErrorCode ierr; 261ace3abfcSBarry Smith PetscBool iascii; 26205db81ecSKris Buschelman PetscViewerFormat format; 26305db81ecSKris Buschelman 26405db81ecSKris Buschelman PetscFunctionBegin; 265b24902e0SBarry Smith ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 2662692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 26732077d6dSBarry Smith if (iascii) { 26805db81ecSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 26905db81ecSKris Buschelman if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 27005db81ecSKris Buschelman ierr = MatFactorInfo_Matlab(A,viewer); 27105db81ecSKris Buschelman } 27205db81ecSKris Buschelman } 27305db81ecSKris Buschelman PetscFunctionReturn(0); 27405db81ecSKris Buschelman } 275f365a357SKris Buschelman 27605db81ecSKris Buschelman 27705db81ecSKris Buschelman /*MC 2782692d6eeSBarry Smith MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance 279e3c5b3baSBarry Smith based ILU factorization (ILUDT) for sequential matrices via the external package MATLAB. 28005db81ecSKris Buschelman 28105db81ecSKris Buschelman 28241c8de11SBarry Smith Works with MATSEQAIJ matrices. 28305db81ecSKris Buschelman 28405db81ecSKris Buschelman Options Database Keys: 285e3c5b3baSBarry Smith . -pc_factor_mat_solver_type matlab - selects MATLAB to do the sparse factorization 28641c8de11SBarry Smith 28705db81ecSKris Buschelman 28805db81ecSKris Buschelman Level: beginner 28905db81ecSKris Buschelman 29005db81ecSKris Buschelman .seealso: PCLU 29141c8de11SBarry Smith 29241c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 29305db81ecSKris Buschelman M*/ 29405db81ecSKris Buschelman 295