Commit db6500dcfb6c82b1630b7a6d35067cd1ee90cf78
1 parent
b5f099f3cf
Exists in
multi
First draft for a multi resolution
Showing 1 changed file with 83 additions and 0 deletions Inline Diff
fvn_sparse/fvn_sparse.f90
| module fvn_sparse | 1 | 1 | module fvn_sparse | |
| use fvn_common | 2 | 2 | use fvn_common | |
| implicit none | 3 | 3 | implicit none | |
| 4 | 4 | |||
| ! Sparse solving | 5 | 5 | ! Sparse solving | |
| interface fvn_sparse_solve | 6 | 6 | interface fvn_sparse_solve | |
| module procedure fvn_zl_sparse_solve,fvn_zi_sparse_solve,fvn_dl_sparse_solve,fvn_di_sparse_solve | 7 | 7 | module procedure fvn_zl_sparse_solve,fvn_zi_sparse_solve,fvn_dl_sparse_solve,fvn_di_sparse_solve | |
| end interface fvn_sparse_solve | 8 | 8 | end interface fvn_sparse_solve | |
| 9 | 9 | |||
| interface fvn_sparse_det | 10 | 10 | interface fvn_sparse_det | |
| module procedure fvn_zl_sparse_det,fvn_zi_sparse_det,fvn_dl_sparse_det,fvn_di_sparse_det | 11 | 11 | module procedure fvn_zl_sparse_det,fvn_zi_sparse_det,fvn_dl_sparse_det,fvn_di_sparse_det | |
| end interface fvn_sparse_det | 12 | 12 | end interface fvn_sparse_det | |
| contains | 13 | 13 | contains | |
| 14 | 14 | |||
| function umfpack_return_code(c) | 15 | 15 | function umfpack_return_code(c) | |
| implicit none | 16 | 16 | implicit none | |
| integer(kind=sp_kind), intent(in) :: c | 17 | 17 | integer(kind=sp_kind), intent(in) :: c | |
| character(len=80) :: umfpack_return_code | 18 | 18 | character(len=80) :: umfpack_return_code | |
| select case(c) | 19 | 19 | select case(c) | |
| case(0) | 20 | 20 | case(0) | |
| umfpack_return_code="UMFPACK_OK" | 21 | 21 | umfpack_return_code="UMFPACK_OK" | |
| case(1) | 22 | 22 | case(1) | |
| umfpack_return_code="UMFPACK_WARNING_singular_matrix" | 23 | 23 | umfpack_return_code="UMFPACK_WARNING_singular_matrix" | |
| case(2) | 24 | 24 | case(2) | |
| umfpack_return_code="UMFPACK_WARNING_determinant_underflow" | 25 | 25 | umfpack_return_code="UMFPACK_WARNING_determinant_underflow" | |
| case(3) | 26 | 26 | case(3) | |
| umfpack_return_code="UMFPACK_WARNING_determinant_overflow" | 27 | 27 | umfpack_return_code="UMFPACK_WARNING_determinant_overflow" | |
| case(-1) | 28 | 28 | case(-1) | |
| umfpack_return_code="UMFPACK_ERROR_out_of_memory" | 29 | 29 | umfpack_return_code="UMFPACK_ERROR_out_of_memory" | |
| case(-3) | 30 | 30 | case(-3) | |
| umfpack_return_code="UMFPACK_ERROR_invalid_Numeric_object" | 31 | 31 | umfpack_return_code="UMFPACK_ERROR_invalid_Numeric_object" | |
| case(-4) | 32 | 32 | case(-4) | |
| umfpack_return_code="UMFPACK_ERROR_invalid_Symbolic_object" | 33 | 33 | umfpack_return_code="UMFPACK_ERROR_invalid_Symbolic_object" | |
| case(-5) | 34 | 34 | case(-5) | |
| umfpack_return_code="UMFPACK_ERROR_argument_missing" | 35 | 35 | umfpack_return_code="UMFPACK_ERROR_argument_missing" | |
| case(-6) | 36 | 36 | case(-6) | |
| umfpack_return_code="UMFPACK_ERROR_n_nonpositive" | 37 | 37 | umfpack_return_code="UMFPACK_ERROR_n_nonpositive" | |
| case(-8) | 38 | 38 | case(-8) | |
| umfpack_return_code="UMFPACK_ERROR_invalid_matrix" | 39 | 39 | umfpack_return_code="UMFPACK_ERROR_invalid_matrix" | |
| case(-11) | 40 | 40 | case(-11) | |
| umfpack_return_code="UMFPACK_ERROR_different_pattern" | 41 | 41 | umfpack_return_code="UMFPACK_ERROR_different_pattern" | |
| case(-13) | 42 | 42 | case(-13) | |
| umfpack_return_code="UMFPACK_ERROR_invalid_system" | 43 | 43 | umfpack_return_code="UMFPACK_ERROR_invalid_system" | |
| case(-15) | 44 | 44 | case(-15) | |
| umfpack_return_code="UMFPACK_ERROR_invalid_permutation" | 45 | 45 | umfpack_return_code="UMFPACK_ERROR_invalid_permutation" | |
| case(-911) | 46 | 46 | case(-911) | |
| umfpack_return_code="UMFPACK_ERROR_internal_error" | 47 | 47 | umfpack_return_code="UMFPACK_ERROR_internal_error" | |
| case(-17) | 48 | 48 | case(-17) | |
| umfpack_return_code="UMFPACK_ERROR_file_IO" | 49 | 49 | umfpack_return_code="UMFPACK_ERROR_file_IO" | |
| case default | 50 | 50 | case default | |
| umfpack_return_code="Unknown return code" | 51 | 51 | umfpack_return_code="Unknown return code" | |
| end select | 52 | 52 | end select | |
| end function | 53 | 53 | end function | |
| 54 | 54 | |||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 55 | 55 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| ! | 56 | 56 | ! | |
| ! SPARSE RESOLUTION | 57 | 57 | ! SPARSE RESOLUTION | |
| ! | 58 | 58 | ! | |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 59 | 59 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| ! | 60 | 60 | ! | |
| ! Sparse resolution is done by interfaçing Tim Davi's UMFPACK | 61 | 61 | ! Sparse resolution is done by interfaçing Tim Davi's UMFPACK | |
| ! http://www.cise.ufl.edu/research/sparse/SuiteSparse/ | 62 | 62 | ! http://www.cise.ufl.edu/research/sparse/SuiteSparse/ | |
| ! Used packages from SuiteSparse : AMD,UMFPACK,UFconfig | 63 | 63 | ! Used packages from SuiteSparse : AMD,UMFPACK,UFconfig | |
| ! | 64 | 64 | ! | |
| ! Solve Ax=B using UMFPACK | 65 | 65 | ! Solve Ax=B using UMFPACK | |
| ! | 66 | 66 | ! | |
| ! Where A is a sparse matrix given in its triplet form | 67 | 67 | ! Where A is a sparse matrix given in its triplet form | |
| ! T -> non zero elements (Tx and Tz for real and imaginary part if complex) | 68 | 68 | ! T -> non zero elements (Tx and Tz for real and imaginary part if complex) | |
| ! Ti,Tj -> row and column index (0-based) of the given elt | 69 | 69 | ! Ti,Tj -> row and column index (0-based) of the given elt | |
| ! n : rank of matrix A | 70 | 70 | ! n : rank of matrix A | |
| ! nz : number of non zero elts | 71 | 71 | ! nz : number of non zero elts | |
| ! | 72 | 72 | ! | |
| ! fvn_*_sparse_solve | 73 | 73 | ! fvn_*_sparse_solve | |
| ! * = zl : double complex + integer(kind=dp_kind) | 74 | 74 | ! * = zl : double complex + integer(kind=dp_kind) | |
| ! * = zi : double complex + integer(kind=sp_kind) | 75 | 75 | ! * = zi : double complex + integer(kind=sp_kind) | |
| ! | 76 | 76 | ! | |
| subroutine fvn_zl_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | 77 | 77 | subroutine fvn_zl_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | |
| implicit none | 78 | 78 | implicit none | |
| integer(kind=dp_kind), intent(in) :: n,nz | 79 | 79 | integer(kind=dp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | 80 | 80 | real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
| integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 81 | 81 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | 82 | 82 | real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | |
| complex(kind=dp_kind),dimension(n),intent(out) :: x | 83 | 83 | complex(kind=dp_kind),dimension(n),intent(out) :: x | |
| integer(kind=dp_kind), intent(out) :: status | 84 | 84 | integer(kind=dp_kind), intent(out) :: status | |
| real(kind=dp_kind), dimension(3), optional, intent(out) :: det | 85 | 85 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det | |
| 86 | 86 | |||
| real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 87 | 87 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
| integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 88 | 88 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
| integer(kind=dp_kind) :: symbolic,numeric | 89 | 89 | integer(kind=dp_kind) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(:),allocatable :: xx,xz | 90 | 90 | real(kind=dp_kind),dimension(:),allocatable :: xx,xz | |
| real(kind=dp_kind),dimension(90) :: info | 91 | 91 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 92 | 92 | real(kind=dp_kind),dimension(20) :: control | |
| integer(kind=dp_kind) :: sys | 93 | 93 | integer(kind=dp_kind) :: sys | |
| 94 | 94 | |||
| 95 | 95 | |||
| status=0 | 96 | 96 | status=0 | |
| 97 | 97 | |||
| allocate(Ax(nz),Az(nz)) | 98 | 98 | allocate(Ax(nz),Az(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 99 | 99 | allocate(Ap(n+1),Ai(nz)) | |
| 100 | 100 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 101 | 101 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | 102 | 102 | call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
| ! if status is not zero a problem has occured | 103 | 103 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 104 | 104 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) | 105 | 105 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) | |
| endif | 106 | 106 | endif | |
| 107 | 107 | |||
| ! Define defaults control values | 108 | 108 | ! Define defaults control values | |
| call umfpack_zl_defaults(control) | 109 | 109 | call umfpack_zl_defaults(control) | |
| 110 | 110 | |||
| ! Symbolic analysis | 111 | 111 | ! Symbolic analysis | |
| call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 112 | 112 | call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
| ! info(1) should be zero | 113 | 113 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 114 | 114 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 115 | 115 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 116 | 116 | status=info(1) | |
| endif | 117 | 117 | endif | |
| 118 | 118 | |||
| ! Numerical factorization | 119 | 119 | ! Numerical factorization | |
| call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 120 | 120 | call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 121 | 121 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 122 | 122 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 123 | 123 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 124 | 124 | status=info(1) | |
| endif | 125 | 125 | endif | |
| 126 | 126 | |||
| ! free the C symbolic pointer | 127 | 127 | ! free the C symbolic pointer | |
| call umfpack_zl_free_symbolic (symbolic) | 128 | 128 | call umfpack_zl_free_symbolic (symbolic) | |
| 129 | 129 | |||
| ! if parameter det is present, the determinant of the matrix is calculated | 130 | 130 | ! if parameter det is present, the determinant of the matrix is calculated | |
| if (present(det) ) then | 131 | 131 | if (present(det) ) then | |
| call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | 132 | 132 | call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
| ! info(1) should be zero | 133 | 133 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 134 | 134 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 135 | 135 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 136 | 136 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 137 | 137 | endif | |
| status=info(1) | 138 | 138 | status=info(1) | |
| endif | 139 | 139 | endif | |
| endif | 140 | 140 | endif | |
| 141 | 141 | |||
| 142 | 142 | |||
| 143 | 143 | |||
| allocate(xx(n),xz(n)) | 144 | 144 | allocate(xx(n),xz(n)) | |
| sys=0 | 145 | 145 | sys=0 | |
| ! sys may be used to define type of solving -> see umfpack.h | 146 | 146 | ! sys may be used to define type of solving -> see umfpack.h | |
| 147 | 147 | |||
| ! Solving | 148 | 148 | ! Solving | |
| call umfpack_zl_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | 149 | 149 | call umfpack_zl_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | |
| ! info(1) should be zero | 150 | 150 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 151 | 151 | if (info(1) /= 0) then | |
| write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 152 | 152 | write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 153 | 153 | status=info(1) | |
| endif | 154 | 154 | endif | |
| 155 | 155 | |||
| 156 | 156 | |||
| ! free the C numeric pointer | 157 | 157 | ! free the C numeric pointer | |
| call umfpack_zl_free_numeric (numeric) | 158 | 158 | call umfpack_zl_free_numeric (numeric) | |
| 159 | 159 | |||
| x=cmplx(xx,xz,dp_kind) | 160 | 160 | x=cmplx(xx,xz,dp_kind) | |
| 161 | 161 | |||
| deallocate(xx,xz) | 162 | 162 | deallocate(xx,xz) | |
| deallocate(Ax,Az) | 163 | 163 | deallocate(Ax,Az) | |
| end subroutine | 164 | 164 | end subroutine | |
| 165 | 165 | |||
| 166 | 166 | |||
| 167 | 167 | |||
| 168 | 168 | |||
| 169 | 169 | |||
| subroutine fvn_zi_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | 170 | 170 | subroutine fvn_zi_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | |
| implicit none | 171 | 171 | implicit none | |
| integer(kind=sp_kind), intent(in) :: n,nz | 172 | 172 | integer(kind=sp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | 173 | 173 | real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
| integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 174 | 174 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | 175 | 175 | real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | |
| complex(kind=dp_kind),dimension(n),intent(out) :: x | 176 | 176 | complex(kind=dp_kind),dimension(n),intent(out) :: x | |
| integer(kind=sp_kind), intent(out) :: status | 177 | 177 | integer(kind=sp_kind), intent(out) :: status | |
| real(kind=dp_kind), dimension(3), optional, intent(out) :: det | 178 | 178 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det | |
| 179 | 179 | |||
| real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 180 | 180 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
| integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 181 | 181 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
| !integer(kind=dp_kind) :: symbolic,numeric | 182 | 182 | !integer(kind=dp_kind) :: symbolic,numeric | |
| integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 183 | 183 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| ! As symbolic and numeric are used to store a C pointer, it is necessary to | 184 | 184 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
| ! still use an integer(kind=dp_kind) for 64bits machines | 185 | 185 | ! still use an integer(kind=dp_kind) for 64bits machines | |
| ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 186 | 186 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(:),allocatable :: xx,xz | 187 | 187 | real(kind=dp_kind),dimension(:),allocatable :: xx,xz | |
| real(kind=dp_kind),dimension(90) :: info | 188 | 188 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 189 | 189 | real(kind=dp_kind),dimension(20) :: control | |
| integer(kind=sp_kind) :: sys | 190 | 190 | integer(kind=sp_kind) :: sys | |
| 191 | 191 | |||
| status=0 | 192 | 192 | status=0 | |
| allocate(Ax(nz),Az(nz)) | 193 | 193 | allocate(Ax(nz),Az(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 194 | 194 | allocate(Ap(n+1),Ai(nz)) | |
| 195 | 195 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 196 | 196 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | 197 | 197 | call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
| ! if status is not zero a problem has occured | 198 | 198 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 199 | 199 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) | 200 | 200 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) | |
| endif | 201 | 201 | endif | |
| 202 | 202 | |||
| ! Define defaults control values | 203 | 203 | ! Define defaults control values | |
| call umfpack_zi_defaults(control) | 204 | 204 | call umfpack_zi_defaults(control) | |
| 205 | 205 | |||
| ! Symbolic analysis | 206 | 206 | ! Symbolic analysis | |
| call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 207 | 207 | call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
| ! info(1) should be zero | 208 | 208 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 209 | 209 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 210 | 210 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 211 | 211 | status=info(1) | |
| endif | 212 | 212 | endif | |
| 213 | 213 | |||
| ! Numerical factorization | 214 | 214 | ! Numerical factorization | |
| call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 215 | 215 | call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 216 | 216 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 217 | 217 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 218 | 218 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 219 | 219 | status=info(1) | |
| endif | 220 | 220 | endif | |
| 221 | 221 | |||
| ! free the C symbolic pointer | 222 | 222 | ! free the C symbolic pointer | |
| call umfpack_zi_free_symbolic (symbolic) | 223 | 223 | call umfpack_zi_free_symbolic (symbolic) | |
| 224 | 224 | |||
| ! if parameter det is present, the determinant of the matrix is calculated | 225 | 225 | ! if parameter det is present, the determinant of the matrix is calculated | |
| if (present(det) ) then | 226 | 226 | if (present(det) ) then | |
| call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | 227 | 227 | call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
| ! info(1) should be zero | 228 | 228 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 229 | 229 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 230 | 230 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 231 | 231 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 232 | 232 | endif | |
| status=info(1) | 233 | 233 | status=info(1) | |
| endif | 234 | 234 | endif | |
| endif | 235 | 235 | endif | |
| 236 | 236 | |||
| 237 | 237 | |||
| 238 | 238 | |||
| 239 | 239 | |||
| allocate(xx(n),xz(n)) | 240 | 240 | allocate(xx(n),xz(n)) | |
| sys=0 | 241 | 241 | sys=0 | |
| ! sys may be used to define type of solving -> see umfpack.h | 242 | 242 | ! sys may be used to define type of solving -> see umfpack.h | |
| 243 | 243 | |||
| ! Solving | 244 | 244 | ! Solving | |
| call umfpack_zi_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | 245 | 245 | call umfpack_zi_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | |
| ! info(1) should be zero | 246 | 246 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 247 | 247 | if (info(1) /= 0) then | |
| write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 248 | 248 | write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 249 | 249 | status=info(1) | |
| endif | 250 | 250 | endif | |
| 251 | 251 | |||
| ! free the C numeric pointer | 252 | 252 | ! free the C numeric pointer | |
| call umfpack_zi_free_numeric (numeric) | 253 | 253 | call umfpack_zi_free_numeric (numeric) | |
| 254 | 254 | |||
| x=cmplx(xx,xz,dp_kind) | 255 | 255 | x=cmplx(xx,xz,dp_kind) | |
| 256 | 256 | |||
| deallocate(xx,xz) | 257 | 257 | deallocate(xx,xz) | |
| deallocate(Ax,Az) | 258 | 258 | deallocate(Ax,Az) | |
| end subroutine | 259 | 259 | end subroutine | |
| 260 | 260 | |||
| 261 | 261 | |||
| 262 | 262 | |||
| 263 | 263 | |||
| 264 | 264 | |||
| 265 | 265 | |||
| subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 266 | 266 | subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
| implicit none | 267 | 267 | implicit none | |
| integer(kind=dp_kind), intent(in) :: n,nz | 268 | 268 | integer(kind=dp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: T | 269 | 269 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |
| integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 270 | 270 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| real(kind=dp_kind),dimension(n),intent(in) :: B | 271 | 271 | real(kind=dp_kind),dimension(n),intent(in) :: B | |
| real(kind=dp_kind),dimension(n),intent(out) :: x | 272 | 272 | real(kind=dp_kind),dimension(n),intent(out) :: x | |
| integer(kind=dp_kind), intent(out) :: status | 273 | 273 | integer(kind=dp_kind), intent(out) :: status | |
| real(kind=dp_kind), dimension(2), optional, intent(out) :: det | 274 | 274 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det | |
| 275 | 275 | |||
| real(kind=dp_kind),dimension(:),allocatable :: A | 276 | 276 | real(kind=dp_kind),dimension(:),allocatable :: A | |
| integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 277 | 277 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
| !integer(kind=dp_kind) :: symbolic,numeric | 278 | 278 | !integer(kind=dp_kind) :: symbolic,numeric | |
| integer(kind=dp_kind) :: symbolic,numeric | 279 | 279 | integer(kind=dp_kind) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(90) :: info | 280 | 280 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 281 | 281 | real(kind=dp_kind),dimension(20) :: control | |
| integer(kind=dp_kind) :: sys | 282 | 282 | integer(kind=dp_kind) :: sys | |
| 283 | 283 | |||
| status=0 | 284 | 284 | status=0 | |
| allocate(A(nz)) | 285 | 285 | allocate(A(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 286 | 286 | allocate(Ap(n+1),Ai(nz)) | |
| 287 | 287 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 288 | 288 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_dl_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | 289 | 289 | call umfpack_dl_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
| ! if status is not zero a problem has occured | 290 | 290 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 291 | 291 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_dl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) | 292 | 292 | write(*,*) "Problem during umfpack_dl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) | |
| endif | 293 | 293 | endif | |
| 294 | 294 | |||
| ! Define defaults control values | 295 | 295 | ! Define defaults control values | |
| call umfpack_dl_defaults(control) | 296 | 296 | call umfpack_dl_defaults(control) | |
| 297 | 297 | |||
| ! Symbolic analysis | 298 | 298 | ! Symbolic analysis | |
| call umfpack_dl_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | 299 | 299 | call umfpack_dl_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |
| ! info(1) should be zero | 300 | 300 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 301 | 301 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 302 | 302 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 303 | 303 | status=info(1) | |
| endif | 304 | 304 | endif | |
| 305 | 305 | |||
| ! Numerical factorization | 306 | 306 | ! Numerical factorization | |
| call umfpack_dl_numeric (Ap, Ai, A, symbolic, numeric, control, info) | 307 | 307 | call umfpack_dl_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 308 | 308 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 309 | 309 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 310 | 310 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 311 | 311 | status=info(1) | |
| endif | 312 | 312 | endif | |
| 313 | 313 | |||
| ! free the C symbolic pointer | 314 | 314 | ! free the C symbolic pointer | |
| call umfpack_dl_free_symbolic (symbolic) | 315 | 315 | call umfpack_dl_free_symbolic (symbolic) | |
| 316 | 316 | |||
| ! if parameter det is present, the determinant of the matrix is calculated | 317 | 317 | ! if parameter det is present, the determinant of the matrix is calculated | |
| if (present(det) ) then | 318 | 318 | if (present(det) ) then | |
| call umfpack_dl_get_determinant(det(1),det(2),numeric,info,status) | 319 | 319 | call umfpack_dl_get_determinant(det(1),det(2),numeric,info,status) | |
| ! info(1) should be zero | 320 | 320 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 321 | 321 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 322 | 322 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 323 | 323 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 324 | 324 | endif | |
| status=info(1) | 325 | 325 | status=info(1) | |
| endif | 326 | 326 | endif | |
| endif | 327 | 327 | endif | |
| 328 | 328 | |||
| 329 | 329 | |||
| sys=0 | 330 | 330 | sys=0 | |
| ! sys may be used to define type of solving -> see umfpack.h | 331 | 331 | ! sys may be used to define type of solving -> see umfpack.h | |
| 332 | 332 | |||
| ! Solving | 333 | 333 | ! Solving | |
| call umfpack_dl_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | 334 | 334 | call umfpack_dl_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | |
| ! info(1) should be zero | 335 | 335 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 336 | 336 | if (info(1) /= 0) then | |
| write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 337 | 337 | write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 338 | 338 | status=info(1) | |
| endif | 339 | 339 | endif | |
| 340 | 340 | |||
| ! free the C numeric pointer | 341 | 341 | ! free the C numeric pointer | |
| call umfpack_dl_free_numeric (numeric) | 342 | 342 | call umfpack_dl_free_numeric (numeric) | |
| 343 | 343 | |||
| deallocate(A) | 344 | 344 | deallocate(A) | |
| end subroutine | 345 | 345 | end subroutine | |
| 346 | 346 | |||
| 347 | 347 | |||
| 348 | subroutine fvn_di_sparse_solve_multi(n,nz,T,Ti,Tj,m,B,x,status,det) | |||
| 349 | implicit none | |||
| 350 | integer(kind=sp_kind), intent(in) :: n,nz,m | |||
| 351 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |||
| 352 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |||
| 353 | real(kind=dp_kind),dimension(n,m),intent(in) :: B | |||
| 354 | real(kind=dp_kind),dimension(n,m),intent(out) :: x | |||
| 355 | integer(kind=sp_kind), intent(out) :: status | |||
| 356 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det | |||
| 357 | ||||
| 358 | real(kind=dp_kind),dimension(:),allocatable :: A | |||
| 359 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |||
| 360 | !integer(kind=dp_kind) :: symbolic,numeric | |||
| 361 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |||
| 362 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |||
| 363 | ! still use an integer(kind=dp_kind) for 64bits machines | |||
| 364 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |||
| 365 | real(kind=dp_kind),dimension(90) :: info | |||
| 366 | real(kind=dp_kind),dimension(20) :: control | |||
| 367 | integer(kind=sp_kind) :: sys | |||
| 368 | integer(kind=sp_kind) :: i | |||
| 369 | ||||
| 370 | status=0 | |||
| 371 | allocate(A(nz)) | |||
| 372 | allocate(Ap(n+1),Ai(nz)) | |||
| 373 | ||||
| 374 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |||
| 375 | call umfpack_di_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |||
| 376 | ! if status is not zero a problem has occured | |||
| 377 | if (status /= 0) then | |||
| 378 | write(*,*) "Problem during umfpack_di_triplet_to_col : ",trim(umfpack_return_code(status)) | |||
| 379 | endif | |||
| 380 | ||||
| 381 | ! Define defaults control values | |||
| 382 | call umfpack_di_defaults(control) | |||
| 383 | ||||
| 384 | ! Symbolic analysis | |||
| 385 | call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |||
| 386 | ! info(1) should be zero | |||
| 387 | if (info(1) /= 0) then | |||
| 388 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |||
| 389 | status=info(1) | |||
| 390 | endif | |||
| 391 | ||||
| 392 | ! Numerical factorization | |||
| 393 | call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |||
| 394 | ! info(1) should be zero | |||
| 395 | if (info(1) /= 0) then | |||
| 396 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |||
| 397 | status=info(1) | |||
| 398 | endif | |||
| 399 | ||||
| 400 | ! free the C symbolic pointer | |||
| 401 | call umfpack_di_free_symbolic (symbolic) | |||
| 402 | ||||
| 403 | ! if parameter det is present, the determinant of the matrix is calculated | |||
| 404 | if (present(det) ) then | |||
| 405 | call umfpack_di_get_determinant(det(1),det(2),numeric,info,status) | |||
| 406 | ! info(1) should be zero | |||
| 407 | if (info(1) /= 0) then | |||
| 408 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |||
| 409 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |||
| 410 | endif | |||
| 411 | status=info(1) | |||
| 412 | endif | |||
| 413 | endif | |||
| 414 | ||||
| 415 | sys=0 | |||
| 416 | ! sys may be used to define type of solving -> see umfpack.h | |||
| 417 | do i=1,m | |||
| 418 | ! Solving | |||
| 419 | call umfpack_di_solve (sys, Ap, Ai, A, x(:,i), B(:,i), numeric, control, info) | |||
| 420 | ! info(1) should be zero | |||
| 421 | if (info(1) /= 0) then | |||
| 422 | write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |||
| 423 | status=info(1) | |||
| 424 | endif | |||
| 425 | end do | |||
| 426 | ! free the C numeric pointer | |||
| 427 | call umfpack_di_free_numeric (numeric) | |||
| 428 | ||||
| 429 | deallocate(A) | |||
| 430 | end subroutine | |||
| 348 | 431 | |||
| 349 | 432 | |||
| 350 | 433 | |||
| 351 | 434 | |||
| subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 352 | 435 | subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
| implicit none | 353 | 436 | implicit none | |
| integer(kind=sp_kind), intent(in) :: n,nz | 354 | 437 | integer(kind=sp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: T | 355 | 438 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |
| integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 356 | 439 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| real(kind=dp_kind),dimension(n),intent(in) :: B | 357 | 440 | real(kind=dp_kind),dimension(n),intent(in) :: B | |
| real(kind=dp_kind),dimension(n),intent(out) :: x | 358 | 441 | real(kind=dp_kind),dimension(n),intent(out) :: x | |
| integer(kind=sp_kind), intent(out) :: status | 359 | 442 | integer(kind=sp_kind), intent(out) :: status | |
| real(kind=dp_kind), dimension(2), optional, intent(out) :: det | 360 | 443 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det | |
| 361 | 444 | |||
| real(kind=dp_kind),dimension(:),allocatable :: A | 362 | 445 | real(kind=dp_kind),dimension(:),allocatable :: A | |
| integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 363 | 446 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
| !integer(kind=dp_kind) :: symbolic,numeric | 364 | 447 | !integer(kind=dp_kind) :: symbolic,numeric | |
| integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 365 | 448 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| ! As symbolic and numeric are used to store a C pointer, it is necessary to | 366 | 449 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
| ! still use an integer(kind=dp_kind) for 64bits machines | 367 | 450 | ! still use an integer(kind=dp_kind) for 64bits machines | |
| ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 368 | 451 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(90) :: info | 369 | 452 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 370 | 453 | real(kind=dp_kind),dimension(20) :: control | |
| integer(kind=sp_kind) :: sys | 371 | 454 | integer(kind=sp_kind) :: sys | |
| 372 | 455 | |||
| status=0 | 373 | 456 | status=0 | |
| allocate(A(nz)) | 374 | 457 | allocate(A(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 375 | 458 | allocate(Ap(n+1),Ai(nz)) | |
| 376 | 459 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 377 | 460 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_di_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | 378 | 461 | call umfpack_di_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
| ! if status is not zero a problem has occured | 379 | 462 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 380 | 463 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_di_triplet_to_col : ",trim(umfpack_return_code(status)) | 381 | 464 | write(*,*) "Problem during umfpack_di_triplet_to_col : ",trim(umfpack_return_code(status)) | |
| endif | 382 | 465 | endif | |
| 383 | 466 | |||
| ! Define defaults control values | 384 | 467 | ! Define defaults control values | |
| call umfpack_di_defaults(control) | 385 | 468 | call umfpack_di_defaults(control) | |
| 386 | 469 | |||
| ! Symbolic analysis | 387 | 470 | ! Symbolic analysis | |
| call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | 388 | 471 | call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |
| ! info(1) should be zero | 389 | 472 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 390 | 473 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 391 | 474 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 392 | 475 | status=info(1) | |
| endif | 393 | 476 | endif | |
| 394 | 477 | |||
| ! Numerical factorization | 395 | 478 | ! Numerical factorization | |
| call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | 396 | 479 | call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 397 | 480 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 398 | 481 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 399 | 482 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 400 | 483 | status=info(1) | |
| endif | 401 | 484 | endif | |
| 402 | 485 | |||
| ! free the C symbolic pointer | 403 | 486 | ! free the C symbolic pointer | |
| call umfpack_di_free_symbolic (symbolic) | 404 | 487 | call umfpack_di_free_symbolic (symbolic) | |
| 405 | 488 | |||
| ! if parameter det is present, the determinant of the matrix is calculated | 406 | 489 | ! if parameter det is present, the determinant of the matrix is calculated | |
| if (present(det) ) then | 407 | 490 | if (present(det) ) then | |
| call umfpack_di_get_determinant(det(1),det(2),numeric,info,status) | 408 | 491 | call umfpack_di_get_determinant(det(1),det(2),numeric,info,status) | |
| ! info(1) should be zero | 409 | 492 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 410 | 493 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 411 | 494 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 412 | 495 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 413 | 496 | endif | |
| status=info(1) | 414 | 497 | status=info(1) | |
| endif | 415 | 498 | endif | |
| endif | 416 | 499 | endif | |
| 417 | 500 | |||
| sys=0 | 418 | 501 | sys=0 | |
| ! sys may be used to define type of solving -> see umfpack.h | 419 | 502 | ! sys may be used to define type of solving -> see umfpack.h | |
| ! Solving | 420 | 503 | ! Solving | |
| call umfpack_di_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | 421 | 504 | call umfpack_di_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | |
| ! info(1) should be zero | 422 | 505 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 423 | 506 | if (info(1) /= 0) then | |
| write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 424 | 507 | write(*,*) "Problem during solving : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 425 | 508 | status=info(1) | |
| endif | 426 | 509 | endif | |
| 427 | 510 | |||
| ! free the C numeric pointer | 428 | 511 | ! free the C numeric pointer | |
| call umfpack_di_free_numeric (numeric) | 429 | 512 | call umfpack_di_free_numeric (numeric) | |
| 430 | 513 | |||
| deallocate(A) | 431 | 514 | deallocate(A) | |
| end subroutine | 432 | 515 | end subroutine | |
| 433 | 516 | |||
| 434 | 517 | |||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 435 | 518 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| ! | 436 | 519 | ! | |
| ! SPARSE DETERMINANT | 437 | 520 | ! SPARSE DETERMINANT | |
| ! | 438 | 521 | ! | |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 439 | 522 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| subroutine fvn_zl_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | 440 | 523 | subroutine fvn_zl_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | |
| implicit none | 441 | 524 | implicit none | |
| integer(kind=dp_kind), intent(in) :: n,nz | 442 | 525 | integer(kind=dp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | 443 | 526 | real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
| integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 444 | 527 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| real(kind=dp_kind), dimension(3), intent(out) :: det | 445 | 528 | real(kind=dp_kind), dimension(3), intent(out) :: det | |
| integer(kind=dp_kind), intent(out) :: status | 446 | 529 | integer(kind=dp_kind), intent(out) :: status | |
| 447 | 530 | |||
| real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 448 | 531 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
| integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 449 | 532 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
| integer(kind=dp_kind) :: symbolic,numeric | 450 | 533 | integer(kind=dp_kind) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(90) :: info | 451 | 534 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 452 | 535 | real(kind=dp_kind),dimension(20) :: control | |
| real(kind=dp_kind) :: Mx,Mz,Ex | 453 | 536 | real(kind=dp_kind) :: Mx,Mz,Ex | |
| 454 | 537 | |||
| 455 | 538 | |||
| status=0 | 456 | 539 | status=0 | |
| 457 | 540 | |||
| allocate(Ax(nz),Az(nz)) | 458 | 541 | allocate(Ax(nz),Az(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 459 | 542 | allocate(Ap(n+1),Ai(nz)) | |
| 460 | 543 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 461 | 544 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | 462 | 545 | call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
| ! if status is not zero a problem has occured | 463 | 546 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 464 | 547 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_zl_triplet_to_col ",trim(umfpack_return_code(int(status,kind=sp_kind))) | 465 | 548 | write(*,*) "Problem during umfpack_zl_triplet_to_col ",trim(umfpack_return_code(int(status,kind=sp_kind))) | |
| endif | 466 | 549 | endif | |
| 467 | 550 | |||
| ! Define defaults control values | 468 | 551 | ! Define defaults control values | |
| call umfpack_zl_defaults(control) | 469 | 552 | call umfpack_zl_defaults(control) | |
| 470 | 553 | |||
| ! Symbolic analysis | 471 | 554 | ! Symbolic analysis | |
| call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 472 | 555 | call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
| ! info(1) should be zero | 473 | 556 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 474 | 557 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 475 | 558 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 476 | 559 | status=info(1) | |
| endif | 477 | 560 | endif | |
| 478 | 561 | |||
| ! Numerical factorization | 479 | 562 | ! Numerical factorization | |
| call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 480 | 563 | call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 481 | 564 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 482 | 565 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 483 | 566 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 484 | 567 | status=info(1) | |
| endif | 485 | 568 | endif | |
| 486 | 569 | |||
| ! free the C symbolic pointer | 487 | 570 | ! free the C symbolic pointer | |
| call umfpack_zl_free_symbolic (symbolic) | 488 | 571 | call umfpack_zl_free_symbolic (symbolic) | |
| 489 | 572 | |||
| call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | 490 | 573 | call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
| ! info(1) should be zero | 491 | 574 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 492 | 575 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 493 | 576 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 494 | 577 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 495 | 578 | endif | |
| status=info(1) | 496 | 579 | status=info(1) | |
| endif | 497 | 580 | endif | |
| 498 | 581 | |||
| ! free the C numeric pointer | 499 | 582 | ! free the C numeric pointer | |
| call umfpack_zl_free_numeric (numeric) | 500 | 583 | call umfpack_zl_free_numeric (numeric) | |
| 501 | 584 | |||
| deallocate(Ax,Az) | 502 | 585 | deallocate(Ax,Az) | |
| end subroutine | 503 | 586 | end subroutine | |
| 504 | 587 | |||
| 505 | 588 | |||
| subroutine fvn_zi_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | 506 | 589 | subroutine fvn_zi_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | |
| implicit none | 507 | 590 | implicit none | |
| integer(kind=sp_kind), intent(in) :: n,nz | 508 | 591 | integer(kind=sp_kind), intent(in) :: n,nz | |
| real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | 509 | 592 | real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
| integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 510 | 593 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
| integer(kind=sp_kind), intent(out) :: status | 511 | 594 | integer(kind=sp_kind), intent(out) :: status | |
| real(kind=dp_kind), dimension(3), intent(out) :: det | 512 | 595 | real(kind=dp_kind), dimension(3), intent(out) :: det | |
| 513 | 596 | |||
| real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 514 | 597 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
| integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 515 | 598 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
| !integer(kind=dp_kind) :: symbolic,numeric | 516 | 599 | !integer(kind=dp_kind) :: symbolic,numeric | |
| integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 517 | 600 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| ! As symbolic and numeric are used to store a C pointer, it is necessary to | 518 | 601 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
| ! still use an integer(kind=dp_kind) for 64bits machines | 519 | 602 | ! still use an integer(kind=dp_kind) for 64bits machines | |
| ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 520 | 603 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
| real(kind=dp_kind),dimension(90) :: info | 521 | 604 | real(kind=dp_kind),dimension(90) :: info | |
| real(kind=dp_kind),dimension(20) :: control | 522 | 605 | real(kind=dp_kind),dimension(20) :: control | |
| 523 | 606 | |||
| status=0 | 524 | 607 | status=0 | |
| allocate(Ax(nz),Az(nz)) | 525 | 608 | allocate(Ax(nz),Az(nz)) | |
| allocate(Ap(n+1),Ai(nz)) | 526 | 609 | allocate(Ap(n+1),Ai(nz)) | |
| 527 | 610 | |||
| ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 528 | 611 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
| call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | 529 | 612 | call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
| ! if status is not zero a problem has occured | 530 | 613 | ! if status is not zero a problem has occured | |
| if (status /= 0) then | 531 | 614 | if (status /= 0) then | |
| write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) | 532 | 615 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) | |
| endif | 533 | 616 | endif | |
| 534 | 617 | |||
| ! Define defaults control values | 535 | 618 | ! Define defaults control values | |
| call umfpack_zi_defaults(control) | 536 | 619 | call umfpack_zi_defaults(control) | |
| 537 | 620 | |||
| ! Symbolic analysis | 538 | 621 | ! Symbolic analysis | |
| call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 539 | 622 | call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
| ! info(1) should be zero | 540 | 623 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 541 | 624 | if (info(1) /= 0) then | |
| write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 542 | 625 | write(*,*) "Problem during symbolic analysis : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 543 | 626 | status=info(1) | |
| endif | 544 | 627 | endif | |
| 545 | 628 | |||
| ! Numerical factorization | 546 | 629 | ! Numerical factorization | |
| call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 547 | 630 | call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
| ! info(1) should be zero | 548 | 631 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 549 | 632 | if (info(1) /= 0) then | |
| write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 550 | 633 | write(*,*) "Problem during numerical factorization : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| status=info(1) | 551 | 634 | status=info(1) | |
| endif | 552 | 635 | endif | |
| 553 | 636 | |||
| ! free the C symbolic pointer | 554 | 637 | ! free the C symbolic pointer | |
| call umfpack_zi_free_symbolic (symbolic) | 555 | 638 | call umfpack_zi_free_symbolic (symbolic) | |
| 556 | 639 | |||
| call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | 557 | 640 | call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
| ! info(1) should be zero | 558 | 641 | ! info(1) should be zero | |
| if (info(1) /= 0) then | 559 | 642 | if (info(1) /= 0) then | |
| if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | 560 | 643 | if ( (info(1) < 1) .or. (info(1) >3) ) then ! not a warning | |
| write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | 561 | 644 | write(*,*) "Problem during sparse determinant : ",trim(umfpack_return_code(int(info(1),kind=sp_kind))) | |
| endif | 562 | 645 | endif | |
| status=info(1) | 563 | 646 | status=info(1) | |
| endif | 564 | 647 | endif | |
| 565 | 648 | |||
| ! free the C numeric pointer | 566 | 649 | ! free the C numeric pointer | |
| call umfpack_zi_free_numeric (numeric) | 567 | 650 | call umfpack_zi_free_numeric (numeric) | |
| 568 | 651 | |||
| deallocate(Ax,Az) | 569 | 652 | deallocate(Ax,Az) | |
| end subroutine | 570 | 653 | end subroutine | |
| 571 | 654 | |||
| subroutine fvn_dl_sparse_det(n,nz,T,Ti,Tj,det,status) | 572 | 655 | subroutine fvn_dl_sparse_det(n,nz,T,Ti,Tj,det,status) | |
| implicit none | 573 | 656 | implicit none | |
| integer(kind=dp_kind), intent(in) :: n,nz | 574 | 657 | integer(kind=dp_kind), intent(in) :: n,nz |