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 typedef struct { 13 PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 14 PetscErrorCode (*MatView)(Mat,PetscViewer); 15 PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 16 PetscErrorCode (*MatILUDTFactor)(Mat,IS,IS,MatFactorInfo*,Mat*); 17 PetscErrorCode (*MatDestroy)(Mat); 18 } Mat_Matlab; 19 20 21 EXTERN_C_BEGIN 22 #undef __FUNCT__ 23 #define __FUNCT__ "MatMatlabEnginePut_Matlab" 24 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine) 25 { 26 PetscErrorCode ierr; 27 Mat B = (Mat)obj; 28 mxArray *mat; 29 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 30 31 PetscFunctionBegin; 32 mat = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL); 33 ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 34 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 35 ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 36 ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr); 37 38 /* Matlab indices start at 0 for sparse (what a surprise) */ 39 40 ierr = PetscObjectName(obj);CHKERRQ(ierr); 41 engPutVariable((Engine *)mengine,obj->name,mat); 42 PetscFunctionReturn(0); 43 } 44 EXTERN_C_END 45 46 EXTERN_C_BEGIN 47 #undef __FUNCT__ 48 #define __FUNCT__ "MatMatlabEngineGet_Matlab" 49 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine) 50 { 51 PetscErrorCode ierr; 52 int ii; 53 Mat mat = (Mat)obj; 54 Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 55 mxArray *mmat; 56 57 PetscFunctionBegin; 58 ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr); 59 60 mmat = engGetVariable((Engine *)mengine,obj->name); 61 62 aij->nz = (mxGetJc(mmat))[mat->rmap.n]; 63 ierr = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr); 64 aij->singlemalloc = PETSC_TRUE; 65 66 ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 67 /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 68 ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 69 ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr); 70 71 for (ii=0; ii<mat->rmap.n; ii++) { 72 aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 73 } 74 75 ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76 ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 77 78 PetscFunctionReturn(0); 79 } 80 EXTERN_C_END 81 82 EXTERN_C_BEGIN 83 #undef __FUNCT__ 84 #define __FUNCT__ "MatConvert_Matlab_SeqAIJ" 85 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Matlab_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat) 86 { 87 PetscErrorCode ierr; 88 Mat B=*newmat; 89 Mat_Matlab *lu=(Mat_Matlab*)A->spptr; 90 91 PetscFunctionBegin; 92 if (reuse == MAT_INITIAL_MATRIX) { 93 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 94 } 95 B->ops->duplicate = lu->MatDuplicate; 96 B->ops->view = lu->MatView; 97 B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic; 98 B->ops->iludtfactor = lu->MatILUDTFactor; 99 B->ops->destroy = lu->MatDestroy; 100 101 ierr = PetscFree(lu);CHKERRQ(ierr); 102 103 ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr); 104 ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 105 ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr); 106 ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr); 107 108 ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 109 *newmat = B; 110 PetscFunctionReturn(0); 111 } 112 EXTERN_C_END 113 114 #undef __FUNCT__ 115 #define __FUNCT__ "MatDestroy_Matlab" 116 PetscErrorCode MatDestroy_Matlab(Mat A) 117 { 118 PetscErrorCode ierr; 119 120 PetscFunctionBegin; 121 ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 122 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 123 PetscFunctionReturn(0); 124 } 125 126 #undef __FUNCT__ 127 #define __FUNCT__ "MatSolve_Matlab" 128 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x) 129 { 130 PetscErrorCode ierr; 131 const char *_A,*_b,*_x; 132 133 PetscFunctionBegin; 134 /* make sure objects have names; use default if not */ 135 ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 136 ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 137 138 ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 139 ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 140 ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 141 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr); 142 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr); 143 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr); 144 /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr); */ 145 ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr); 146 PetscFunctionReturn(0); 147 } 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "MatLUFactorNumeric_Matlab" 151 PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F) 152 { 153 PetscErrorCode ierr; 154 size_t len; 155 char *_A,*name; 156 157 PetscFunctionBegin; 158 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr); 159 _A = A->name; 160 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr); 161 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr); 162 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 163 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 164 sprintf(name,"_%s",_A); 165 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 166 ierr = PetscFree(name);CHKERRQ(ierr); 167 PetscFunctionReturn(0); 168 } 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "MatLUFactorSymbolic_Matlab" 172 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 173 { 174 PetscErrorCode ierr; 175 176 PetscFunctionBegin; 177 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 178 ierr = MatCreate(A->comm,F);CHKERRQ(ierr); 179 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 180 ierr = MatSetType(*F,A->type_name);CHKERRQ(ierr); 181 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 182 (*F)->ops->solve = MatSolve_Matlab; 183 (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab; 184 (*F)->factor = FACTOR_LU; 185 PetscFunctionReturn(0); 186 } 187 188 /* ---------------------------------------------------------------------------------*/ 189 #undef __FUNCT__ 190 #define __FUNCT__ "MatSolve_Matlab_QR" 191 PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x) 192 { 193 PetscErrorCode ierr; 194 const char *_A,*_b,*_x; 195 196 PetscFunctionBegin; 197 /* make sure objects have names; use default if not */ 198 ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr); 199 ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr); 200 201 ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr); 202 ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr); 203 ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr); 204 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr); 205 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr); 206 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr); 207 /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr); */ 208 ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr); 209 PetscFunctionReturn(0); 210 } 211 212 #undef __FUNCT__ 213 #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR" 214 PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F) 215 { 216 PetscErrorCode ierr; 217 size_t len; 218 char *_A,*name; 219 220 PetscFunctionBegin; 221 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr); 222 _A = A->name; 223 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr); 224 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 225 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 226 sprintf(name,"_%s",_A); 227 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 228 ierr = PetscFree(name);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR" 234 PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 235 { 236 PetscErrorCode ierr; 237 238 PetscFunctionBegin; 239 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 240 ierr = MatCreate(A->comm,F);CHKERRQ(ierr); 241 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 242 ierr = MatSetType(*F,A->type_name);CHKERRQ(ierr); 243 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 244 (*F)->ops->solve = MatSolve_Matlab_QR; 245 (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR; 246 (*F)->factor = FACTOR_LU; 247 (*F)->assembled = PETSC_TRUE; /* required by -ksp_view */ 248 249 PetscFunctionReturn(0); 250 } 251 252 /* --------------------------------------------------------------------------------*/ 253 #undef __FUNCT__ 254 #define __FUNCT__ "MatILUDTFactor_Matlab" 255 PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F) 256 { 257 PetscErrorCode ierr; 258 size_t len; 259 char *_A,*name; 260 261 PetscFunctionBegin; 262 if (info->dt == PETSC_DEFAULT) info->dt = .005; 263 if (info->dtcol == PETSC_DEFAULT) info->dtcol = .01; 264 if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 265 ierr = MatCreate(A->comm,F);CHKERRQ(ierr); 266 ierr = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 267 ierr = MatSetType(*F,A->type_name);CHKERRQ(ierr); 268 ierr = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr); 269 (*F)->ops->solve = MatSolve_Matlab; 270 (*F)->factor = FACTOR_LU; 271 ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr); 272 _A = A->name; 273 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr); 274 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr); 275 ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr); 276 277 ierr = PetscStrlen(_A,&len);CHKERRQ(ierr); 278 ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr); 279 sprintf(name,"_%s",_A); 280 ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr); 281 ierr = PetscFree(name);CHKERRQ(ierr); 282 PetscFunctionReturn(0); 283 } 284 285 #undef __FUNCT__ 286 #define __FUNCT__ "MatFactorInfo_Matlab" 287 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer) 288 { 289 PetscErrorCode ierr; 290 291 PetscFunctionBegin; 292 ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters: -- not written yet!\n");CHKERRQ(ierr); 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "MatView_Matlab" 298 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) 299 { 300 PetscErrorCode ierr; 301 PetscTruth iascii; 302 PetscViewerFormat format; 303 Mat_Matlab *lu=(Mat_Matlab*)(A->spptr); 304 305 PetscFunctionBegin; 306 ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr); 307 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 308 if (iascii) { 309 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 310 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 311 ierr = MatFactorInfo_Matlab(A,viewer); 312 } 313 } 314 PetscFunctionReturn(0); 315 } 316 317 #undef __FUNCT__ 318 #define __FUNCT__ "MatDuplicate_Matlab" 319 PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M) 320 { 321 PetscErrorCode ierr; 322 Mat_Matlab *lu=(Mat_Matlab*)A->spptr; 323 324 PetscFunctionBegin; 325 ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 326 ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr); 327 PetscFunctionReturn(0); 328 } 329 330 EXTERN_C_BEGIN 331 #undef __FUNCT__ 332 #define __FUNCT__ "MatConvert_SeqAIJ_Matlab" 333 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,MatType type,MatReuse reuse,Mat *newmat) 334 { 335 PetscErrorCode ierr; 336 Mat B=*newmat; 337 Mat_Matlab *lu; 338 PetscTruth qr; 339 340 PetscFunctionBegin; 341 if (reuse == MAT_INITIAL_MATRIX) { 342 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 343 } 344 345 ierr = PetscNewLog(B,Mat_Matlab,&lu);CHKERRQ(ierr); 346 lu->MatDuplicate = A->ops->duplicate; 347 lu->MatView = A->ops->view; 348 lu->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 349 lu->MatILUDTFactor = A->ops->iludtfactor; 350 lu->MatDestroy = A->ops->destroy; 351 352 B->spptr = (void*)lu; 353 B->ops->duplicate = MatDuplicate_Matlab; 354 B->ops->view = MatView_Matlab; 355 B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab; 356 B->ops->iludtfactor = MatILUDTFactor_Matlab; 357 B->ops->destroy = MatDestroy_Matlab; 358 359 ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr); 360 if (qr) { 361 B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR; 362 ierr = PetscInfo(0,"Using Matlab QR with iterative refinement for LU factorization and solves\n");CHKERRQ(ierr); 363 } else { 364 ierr = PetscInfo(0,"Using Matlab for LU factorizations and solves.\n");CHKERRQ(ierr); 365 } 366 ierr = PetscInfo(0,"Using Matlab for ILUDT factorizations and solves.\n");CHKERRQ(ierr); 367 368 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C", 369 "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr); 370 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C", 371 "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr); 372 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C", 373 "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr); 374 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C", 375 "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr); 376 ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr); 377 *newmat = B; 378 PetscFunctionReturn(0); 379 } 380 EXTERN_C_END 381 382 /*MC 383 MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance 384 based ILU factorization (ILUDT) for sequential matrices via the external package Matlab. 385 386 If Matlab is instaled (see the manual for 387 instructions on how to declare the existence of external packages), 388 a matrix type can be constructed which invokes Matlab solvers. 389 After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB). 390 This matrix type is only supported for double precision real. 391 392 This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 393 supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 394 the MATSEQAIJ type without data copy. 395 396 Options Database Keys: 397 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions() 398 - -mat_matlab_qr - sets the direct solver to be QR instead of LU 399 400 Level: beginner 401 402 .seealso: PCLU 403 M*/ 404 405 EXTERN_C_BEGIN 406 #undef __FUNCT__ 407 #define __FUNCT__ "MatCreate_Matlab" 408 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A) 409 { 410 PetscErrorCode ierr; 411 412 PetscFunctionBegin; 413 ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); 414 ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 415 PetscFunctionReturn(0); 416 } 417 EXTERN_C_END 418