1e8aa55a4SKris Buschelman /*$Id: essl.c,v 1.49 2001/08/07 03:02:47 balay Exp $*/ 2e8aa55a4SKris Buschelman 3e8aa55a4SKris Buschelman /* 4e8aa55a4SKris Buschelman Provides an interface to the IBM RS6000 Essl sparse solver 5e8aa55a4SKris Buschelman 6e8aa55a4SKris Buschelman */ 7e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h" 8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work! */ 9e8aa55a4SKris Buschelman 10e8aa55a4SKris Buschelman typedef struct { 11e8aa55a4SKris Buschelman int n,nz; 12e8aa55a4SKris Buschelman PetscScalar *a; 13e8aa55a4SKris Buschelman int *ia; 14e8aa55a4SKris Buschelman int *ja; 15e8aa55a4SKris Buschelman int lna; 16e8aa55a4SKris Buschelman int iparm[5]; 17e8aa55a4SKris Buschelman PetscReal rparm[5]; 18e8aa55a4SKris Buschelman PetscReal oparm[5]; 19e8aa55a4SKris Buschelman PetscScalar *aux; 20e8aa55a4SKris Buschelman int naux; 21e8aa55a4SKris Buschelman 22f0c56d0fSKris Buschelman int (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 23460c4903SKris Buschelman int (*MatAssemblyEnd)(Mat,MatAssemblyType); 24460c4903SKris Buschelman int (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 25e8aa55a4SKris Buschelman int (*MatDestroy)(Mat); 262f71e704SKris Buschelman PetscTruth CleanUpESSL; 27f0c56d0fSKris Buschelman } Mat_Essl; 28f0c56d0fSKris Buschelman 29f0c56d0fSKris Buschelman EXTERN int MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*); 30e8aa55a4SKris Buschelman 31460c4903SKris Buschelman EXTERN_C_BEGIN 32460c4903SKris Buschelman #undef __FUNCT__ 33460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ" 348e9aea5cSBarry Smith int MatConvert_Essl_SeqAIJ(Mat A,const MatType type,Mat *newmat) { 35460c4903SKris Buschelman int ierr; 36460c4903SKris Buschelman Mat B=*newmat; 37f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 38460c4903SKris Buschelman 39460c4903SKris Buschelman PetscFunctionBegin; 40460c4903SKris Buschelman if (B != A) { 41460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); 42f0c56d0fSKris Buschelman } 43f0c56d0fSKris Buschelman B->ops->duplicate = essl->MatDuplicate; 44f0c56d0fSKris Buschelman B->ops->assemblyend = essl->MatAssemblyEnd; 452f71e704SKris Buschelman B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic; 462f71e704SKris Buschelman B->ops->destroy = essl->MatDestroy; 472f71e704SKris Buschelman 48460c4903SKris Buschelman /* free the Essl datastructures */ 49460c4903SKris Buschelman ierr = PetscFree(essl);CHKERRQ(ierr); 50460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 51460c4903SKris Buschelman *newmat = B; 52460c4903SKris Buschelman PetscFunctionReturn(0); 53460c4903SKris Buschelman } 54460c4903SKris Buschelman EXTERN_C_END 55460c4903SKris Buschelman 56e8aa55a4SKris Buschelman #undef __FUNCT__ 57f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl" 58f0c56d0fSKris Buschelman int MatDestroy_Essl(Mat A) { 59460c4903SKris Buschelman int ierr; 60f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 61e8aa55a4SKris Buschelman 62e8aa55a4SKris Buschelman PetscFunctionBegin; 632f71e704SKris Buschelman if (essl->CleanUpESSL) { 642f71e704SKris Buschelman ierr = PetscFree(essl->a);CHKERRQ(ierr); 65e8aa55a4SKris Buschelman } 662f71e704SKris Buschelman ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,&A); 672f71e704SKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 68460c4903SKris Buschelman PetscFunctionReturn(0); 69460c4903SKris Buschelman } 70460c4903SKris Buschelman 71460c4903SKris Buschelman #undef __FUNCT__ 72f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl" 73f0c56d0fSKris Buschelman int MatSolve_Essl(Mat A,Vec b,Vec x) { 74f0c56d0fSKris Buschelman Mat_Essl *essl = (Mat_Essl*)A->spptr; 75e8aa55a4SKris Buschelman PetscScalar *xx; 76e8aa55a4SKris Buschelman int ierr,m,zero = 0; 77e8aa55a4SKris Buschelman 78e8aa55a4SKris Buschelman PetscFunctionBegin; 79e8aa55a4SKris Buschelman ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr); 80e8aa55a4SKris Buschelman ierr = VecCopy(b,x);CHKERRQ(ierr); 81e8aa55a4SKris Buschelman ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 82e8aa55a4SKris Buschelman dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 83e8aa55a4SKris Buschelman ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 84e8aa55a4SKris Buschelman PetscFunctionReturn(0); 85e8aa55a4SKris Buschelman } 86e8aa55a4SKris Buschelman 87e8aa55a4SKris Buschelman #undef __FUNCT__ 88f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl" 89f0c56d0fSKris Buschelman int MatLUFactorNumeric_Essl(Mat A,Mat *F) { 90e8aa55a4SKris Buschelman Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data; 91f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(*F)->spptr; 92e8aa55a4SKris Buschelman int i,ierr,one = 1; 93e8aa55a4SKris Buschelman 94e8aa55a4SKris Buschelman PetscFunctionBegin; 95e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 96e8aa55a4SKris Buschelman for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1; 97e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 98e8aa55a4SKris Buschelman 99e8aa55a4SKris Buschelman ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr); 100e8aa55a4SKris Buschelman 101e8aa55a4SKris Buschelman /* set Essl options */ 102e8aa55a4SKris Buschelman essl->iparm[0] = 1; 103e8aa55a4SKris Buschelman essl->iparm[1] = 5; 104e8aa55a4SKris Buschelman essl->iparm[2] = 1; 105e8aa55a4SKris Buschelman essl->iparm[3] = 0; 106e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 107e8aa55a4SKris Buschelman essl->rparm[1] = A->lupivotthreshold; 108e8aa55a4SKris Buschelman 109e8aa55a4SKris Buschelman dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 110e8aa55a4SKris Buschelman essl->rparm,essl->oparm,essl->aux,&essl->naux); 111e8aa55a4SKris Buschelman 112e8aa55a4SKris Buschelman PetscFunctionReturn(0); 113e8aa55a4SKris Buschelman } 114e8aa55a4SKris Buschelman 115e8aa55a4SKris Buschelman #undef __FUNCT__ 116f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl" 117f0c56d0fSKris Buschelman int MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 118e8aa55a4SKris Buschelman Mat B; 119eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 120eef49c96SKris Buschelman int ierr,len; 121f0c56d0fSKris Buschelman Mat_Essl *essl; 122e8aa55a4SKris Buschelman PetscReal f = 1.0; 123e8aa55a4SKris Buschelman 124e8aa55a4SKris Buschelman PetscFunctionBegin; 125e8aa55a4SKris Buschelman if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 126e8aa55a4SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr); 127*be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 128e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 129e8aa55a4SKris Buschelman 130f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 131f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 132e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 133e8aa55a4SKris Buschelman 134f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 135e8aa55a4SKris Buschelman 136e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 137e8aa55a4SKris Buschelman f = info->fill; 138e8aa55a4SKris Buschelman essl->nz = a->nz; 139e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 140e8aa55a4SKris Buschelman essl->naux = 100 + 10*A->m; 141e8aa55a4SKris Buschelman 142e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 143e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 144e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 145e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 146e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 147e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1482f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 149e8aa55a4SKris Buschelman 150f0c56d0fSKris Buschelman PetscLogObjectMemory(B,len+sizeof(Mat_Essl)); 151e8aa55a4SKris Buschelman *F = B; 152e8aa55a4SKris Buschelman PetscFunctionReturn(0); 153e8aa55a4SKris Buschelman } 154e8aa55a4SKris Buschelman 1552f71e704SKris Buschelman #undef __FUNCT__ 156f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 157f0c56d0fSKris Buschelman int MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) { 1582f71e704SKris Buschelman int ierr; 159f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1602f71e704SKris Buschelman 1612f71e704SKris Buschelman PetscFunctionBegin; 1622f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1632f71e704SKris Buschelman 1642f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 165f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 166f0c56d0fSKris Buschelman PetscLogInfo(0,"Using ESSL for LU factorization and solves"); 1672f71e704SKris Buschelman PetscFunctionReturn(0); 1682f71e704SKris Buschelman } 1692f71e704SKris Buschelman 170460c4903SKris Buschelman EXTERN_C_BEGIN 171e8aa55a4SKris Buschelman #undef __FUNCT__ 172460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 1738e9aea5cSBarry Smith int MatConvert_SeqAIJ_Essl(Mat A,const MatType type,Mat *newmat) { 174460c4903SKris Buschelman Mat B=*newmat; 175460c4903SKris Buschelman int ierr; 176f0c56d0fSKris Buschelman Mat_Essl *essl; 177460c4903SKris Buschelman 178e8aa55a4SKris Buschelman PetscFunctionBegin; 179460c4903SKris Buschelman 180460c4903SKris Buschelman if (B != A) { 181460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 182460c4903SKris Buschelman } 183460c4903SKris Buschelman 184f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 185f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 186460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 187460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 188460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 1892f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 190460c4903SKris Buschelman 1912f71e704SKris Buschelman B->spptr = (void *)essl; 192f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 193f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 194f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 195f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 196460c4903SKris Buschelman 197460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 198460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 199460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 200460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 201460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 202460c4903SKris Buschelman *newmat = B; 203e8aa55a4SKris Buschelman PetscFunctionReturn(0); 204e8aa55a4SKris Buschelman } 205460c4903SKris Buschelman EXTERN_C_END 206e8aa55a4SKris Buschelman 207f0c56d0fSKris Buschelman #undef __FUNCT__ 208f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 209f0c56d0fSKris Buschelman int MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) { 210f0c56d0fSKris Buschelman int ierr; 21113ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2128f340917SKris Buschelman 213f0c56d0fSKris Buschelman PetscFunctionBegin; 2148f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 215f0c56d0fSKris Buschelman ierr = MatConvert_SeqAIJ_Essl(*M,MATESSL,M);CHKERRQ(ierr); 2163f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 217f0c56d0fSKris Buschelman PetscFunctionReturn(0); 218f0c56d0fSKris Buschelman } 219f0c56d0fSKris Buschelman 2202f71e704SKris Buschelman /*MC 221fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2222f71e704SKris Buschelman via the external package ESSL. 2232f71e704SKris Buschelman 2242f71e704SKris Buschelman If ESSL is installed (see the manual for 2252f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2262f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2272f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2282f71e704SKris Buschelman This matrix type is only supported for double precision real. 2292f71e704SKris Buschelman 2302f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 23128b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 23228b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2332f71e704SKris Buschelman 2342f71e704SKris Buschelman Options Database Keys: 2350bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2362f71e704SKris Buschelman 2372f71e704SKris Buschelman Level: beginner 2382f71e704SKris Buschelman 2392f71e704SKris Buschelman .seealso: PCLU 2402f71e704SKris Buschelman M*/ 2412f71e704SKris Buschelman 242e8aa55a4SKris Buschelman EXTERN_C_BEGIN 243e8aa55a4SKris Buschelman #undef __FUNCT__ 244f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 245f0c56d0fSKris Buschelman int MatCreate_Essl(Mat A) { 246e8aa55a4SKris Buschelman int ierr; 247e8aa55a4SKris Buschelman 248e8aa55a4SKris Buschelman PetscFunctionBegin; 2495441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2505441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 251e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 252460c4903SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr); 253e8aa55a4SKris Buschelman PetscFunctionReturn(0); 254e8aa55a4SKris Buschelman } 2554eb8e494SKris Buschelman EXTERN_C_END 256