32 #define MAXMEM 16000000 !In kilobytes 52 subroutine dgetpartialinv(sizeA, nonzerosA, a, ia, ja, sizeInv, invA, error)
60 TYPE(mkl_pardiso_handle),
pointer :: PT(:) => null()
61 integer*4,
pointer :: idum(:) => null(), pia(:) => null(), pja(:) => null()
62 real(KIND=8), pointer :: ddum(:) => null(), pa(:) => null(), pb(:,:) => null(), px(:,:) => null()
63 INTEGER*4 maxfct, mnum, mtype, phase, nrhs, error, msglvl, i, nnz, numIterations, idxIterations, offset
68 INTEGER*4 sizeA, nonzerosA
69 INTEGER*4,
TARGET :: ia(sizeA+1), ja(nonzerosA)
70 real*8,
TARGET :: a(nonzerosa)
72 INTEGER*4,
ALLOCATABLE :: perm(:)
75 real*8 :: inva(sizeinv,sizeinv)
80 DATA nrhs /1/, maxfct /1/, mnum /1/
81 allocate( pt(64), idum(0), ddum(0) )
94 write(0,*)
'The input matrix: (getPartialInv)' 97 if (jdx >= ia(idx+1))
then 101 if (jdx < ia(idx+1))
then 105 write(0,*)
'The size of the Partial inverse to be calculated:', sizeinv
117 call pardisoinit(pt, mtype, iparm)
154 if (nrhs.GT.sizeinv)
then 162 write(0,*)
'number of right sides: ', nrhs
165 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
166 idum, nrhs, iparm, msglvl, ddum, ddum, error)
167 maxmem = (iparm(16)+iparm(17))
170 write(0,*)
'maxmem: ', maxmem,
' kbytes' 171 write(0,*)
'maxmem total: ', maxmem+sizea*nrhs*16/1000,
' kbytes' 174 IF ((maxmem+sizea*nrhs*16/1000).GT.maxmem)
then 175 nrhs = floor(real(maxmem-maxmem)/real(sizea*16)*1000)
176 write(0,*)
'number of right sides: ', nrhs
184 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
185 idum, nrhs, iparm, msglvl, ddum, ddum, error)
188 write(0,*)
'Reordering and factorization completed ... ' 190 IF (error .NE. 0)
THEN 191 write(0,*)
'The following ERROR was detected at the factorization step: ', error
200 allocate( perm(sizea) )
203 perm(sizea-sizeinv+idx) = 1
207 if (modulo(sizeinv, nrhs).EQ.0)
then 208 numiterations = sizeinv/nrhs
210 numiterations = floor(real(sizeinv)/real(nrhs)) + 1
214 write(0,*)
'Number of iterations to obtain the right solutions ', numiterations
221 allocate( pb(sizea, nrhs) )
222 allocate( px(sizea, nrhs) )
224 do idxiterations = 1, numiterations
226 offset = (idxiterations-1)*nrhs
228 if ((sizeinv-offset).LT.nrhs)
then 229 nrhs = sizeinv-offset
231 allocate( pb(sizea, nrhs) )
232 allocate( px(sizea, nrhs) )
235 if ((sizeinv-offset).LT.nrhs)
then 236 nrhs = sizeinv-offset
243 pb(sizea-sizeinv+offset+idx, idx) = 1.d0
246 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
247 perm, nrhs, iparm, msglvl, pb, px, error)
249 IF (error .NE. 0)
THEN 256 inva(offset+idx,jdx) = px(sizea-sizeinv+jdx, idx)
262 deallocate(pb, px, perm)
265 IF (error .NE. 0)
THEN 266 write(0,*)
'The following ERROR was detected at the solution step: ', error
274 write(0,*)
'row', idx,
'col', jdx,
'element of a = ', inva(jdx, idx)
284 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, ddum, &
286 idum, nrhs, iparm, msglvl, ddum, ddum, error)
288 deallocate(idum, ddum, pt)
290 IF (error .NE. 0)
THEN 291 write(0,*)
'The following ERROR was detected at releasing the memory: ', error
314 subroutine zgetpartialinv(sizeA, nonzerosA, a, ia, ja, sizeInv, real_invA, imag_invA, error)
321 TYPE(mkl_pardiso_handle),
pointer :: PT(:) => null()
322 integer*4,
pointer :: idum(:) => null(), pia(:) => null(), pja(:) => null()
323 complex(KIND=8),
pointer :: ddum(:) => null(), pa(:) => null(), pb(:,:) => null(), px(:,:) => null()
324 INTEGER*4 maxfct, mnum, mtype, phase, nrhs, error, msglvl, nnz, numIterations, idxIterations, offset
329 INTEGER*4 sizeA, nonzerosA
330 INTEGER*4,
TARGET :: ia(sizeA+1), ja(nonzerosA)
331 COMPLEX*16,
TARGET :: a(nonzerosA)
333 INTEGER*4,
ALLOCATABLE :: perm(:)
336 real*8 :: real_inva(sizeinv,sizeinv)
337 real*8 :: imag_inva(sizeinv,sizeinv)
339 INTEGER*4 idx, jdx, maxmem
343 DATA maxfct /1/, mnum /1/
344 allocate( pt(64), idum(0), ddum(0) )
358 write(0,*)
'The input matrix: (getPartialInv)' 360 do jdx = 1, nonzerosa
361 if (jdx >= ia(idx+1))
then 365 if (jdx < ia(idx+1))
then 369 write(0,*)
'The size of the partial inverse to be calculated:', sizeinv
381 call pardisoinit(pt, mtype, iparm)
417 if (nrhs.GT.sizeinv)
then 425 write(0,*)
'number of right sides: ', nrhs
430 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
431 idum, nrhs, iparm, msglvl, ddum, ddum, error)
432 maxmem = (iparm(16)+iparm(17))
435 write(0,*)
'maxmem: ', maxmem,
' kbytes' 436 write(0,*)
'maxmem total: ', maxmem+sizea*nrhs*32/1000,
' kbytes' 439 IF ((maxmem+sizea*nrhs*32/1000).GT.maxmem)
then 440 nrhs = floor(real(maxmem-maxmem)/real(sizea*32)*1000)
441 write(0,*)
'number of right sides: ', nrhs
449 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
450 idum, nrhs, iparm, msglvl, ddum, ddum, error)
453 write(0,*)
'Reordering and factorization completed ... ' 455 IF (error .NE. 0)
THEN 456 write(0,*)
'The following ERROR was detected at the factorization step: ', error
465 allocate( perm(sizea) )
468 perm(sizea-sizeinv+idx) = 1
472 if (modulo(sizeinv, nrhs).EQ.0)
then 473 numiterations = sizeinv/nrhs
475 numiterations = floor(real(sizeinv)/real(nrhs)) + 1
479 write(0,*)
'Number of iterations to obtain the right solutions ', numiterations
483 allocate( pb(sizea, nrhs) )
484 allocate( px(sizea, nrhs) )
486 do idxiterations = 1, numiterations
488 offset = (idxiterations-1)*nrhs
490 if ((sizeinv-offset).LT.nrhs)
then 491 nrhs = sizeinv-offset
493 allocate( pb(sizea, nrhs) )
494 allocate( px(sizea, nrhs) )
501 pb(sizea-sizeinv+offset+idx, idx) = (1.d0, 0.d0)
504 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, pa, pia, pja, &
505 perm, nrhs, iparm, msglvl, pb, px, error)
507 IF (error .NE. 0)
THEN 513 real_inva(offset+idx,jdx) = real(px(sizea-sizeinv+jdx, idx))
514 imag_inva(offset+idx,jdx) = aimag(px(sizea-sizeinv+jdx, idx))
520 deallocate(pb, px, perm)
523 IF (error .NE. 0)
THEN 524 write(0,*)
'The following ERROR was detected at the solution step: ', error
531 CALL pardiso (pt, maxfct, mnum, mtype, phase, sizea, ddum, &
533 idum, nrhs, iparm, msglvl, ddum, ddum, error)
535 deallocate(idum, ddum, pt)
537 IF (error .NE. 0)
THEN 538 write(0,*)
'The following ERROR was detected at releasing the memory: ', error
subroutine zgetpartialinv(sizeA, nonzerosA, a, ia, ja, sizeInv, real_invA, imag_invA, error)
Get the partial inverse of a complex valued real matrices.
Module to calculate the partial inverse of a real/complex sparse matrix via the PARDISO libraries.
subroutine dgetpartialinv(sizeA, nonzerosA, a, ia, ja, sizeInv, invA, error)
Get the partial inverse of double valued real matrices.