Commit db6500dcfb6c82b1630b7a6d35067cd1ee90cf78

Authored by William Daniau
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