2
C This file is part of MUMPS 4.8.4, built on Mon Dec 15 15:31:38 UTC 2008
2
C This file is part of MUMPS 4.9.2, built on Thu Nov 5 07:05:08 UTC 2009
5
5
C This version of MUMPS is provided to you free of charge. It is public
6
6
C domain, based on public domain software developed during the Esprit IV
7
7
C European project PARASOL (1996-1999) by CERFACS, ENSEEIHT-IRIT and RAL.
8
8
C Since this first public domain version in 1999, the developments are
9
C supported by the following institutions: CERFACS, ENSEEIHT-IRIT, and
9
C supported by the following institutions: CERFACS, CNRS, INPT(ENSEEIHT)-
12
C Main contributors are Patrick Amestoy, Iain Duff, Abdou Guermouche,
13
C Jacko Koster, Jean-Yves L'Excellent, and Stephane Pralet.
12
C Current development team includes Patrick Amestoy, Alfredo Buttari,
13
C Abdou Guermouche, Jean-Yves L'Excellent, Bora Ucar.
15
15
C Up-to-date copies of the MUMPS package can be obtained
16
16
C from the Web pages:
24
24
C User documentation of any code that uses this software can
25
25
C include this complete notice. You can acknowledge (using
26
C references [1], [2], and [3]) the contribution of this package
26
C references [1] and [2]) the contribution of this package
27
27
C in any scientific publication dependent upon the use of the
28
28
C package. You shall use reasonable endeavours to notify
29
29
C the authors of the package of this publication.
31
C [1] P. R. Amestoy, I. S. Duff and J.-Y. L'Excellent,
32
C Multifrontal parallel distributed symmetric and unsymmetric solvers,
33
C in Comput. Methods in Appl. Mech. Eng., 184, 501-520 (2000).
35
C [2] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent,
31
C [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent,
36
32
C A fully asynchronous multifrontal solver using distributed dynamic
37
33
C scheduling, SIAM Journal of Matrix Analysis and Applications,
38
34
C Vol 23, No 1, pp 15-41 (2001).
40
C [3] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and
36
C [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and
41
37
C S. Pralet, Hybrid scheduling for the parallel solution of linear
42
38
C systems. Parallel Computing Vol 32 (2), pp 136-156 (2006).
52
48
INTEGER ICNTL(40), KEEP(500), MPG
53
49
KEEP(111)=ICNTL(25)
54
50
IF (KEEP(111) < -1 .OR.
55
* KEEP(111).GT.KEEP(112)+KEEP(17)) THEN
51
& KEEP(111).GT.KEEP(112)+KEEP(17)) THEN
58
54
IF (KEEP(19).EQ.0.AND.KEEP(110).EQ.0) THEN
59
55
IF(KEEP(111).NE.0.AND.MPG.GT.0) THEN
61
*'** Warning: ICNTL(25) option disabled because'
57
&'** Warning: ICNTL(25) option disabled because'
63
*'** null space was not required during factorization'
59
&'** null space was not required during factorization'
67
63
IF (ICNTL(9).NE.1) THEN
68
64
IF (KEEP(111).NE.0.AND. MPG.GT.0) THEN
70
*'** Warning: ICNTL(25) option disabled because'
66
&'** Warning: ICNTL(25) option disabled because'
72
*'** it is not available for the transposed system'
68
&'** it is not available for the transposed system'
93
89
END SUBROUTINE DMUMPS_636
94
90
SUBROUTINE DMUMPS_279( PHASE, MBLOCK, NBLOCK,
96
* LOCAL_M, LOCAL_N, ROOT_OWNER, KEEP,KEEP8,
92
& LOCAL_M, LOCAL_N, ROOT_OWNER, KEEP,KEEP8,
99
95
INTEGER, INTENT(IN) :: PHASE, SIZE_ROOT_ARG
100
96
INTEGER, INTENT(IN) :: MBLOCK, NBLOCK, LOCAL_M, LOCAL_N
149
DOUBLE PRECISION FUNCTION DMUMPS_104(N,AA,WR01)
151
DOUBLE PRECISION AA(N*N),WR01(N)
153
DOUBLE PRECISION ZERO
154
DOUBLE PRECISION VALUE
155
PARAMETER(ZERO=0.0D0)
157
CALL DMUMPS_117(N,ZERO,WR01,1)
161
WR01(I)=WR01(I)+abs(AA(J))
166
VALUE=max(abs(VALUE),abs(WR01(I)))
144
END SUBROUTINE DMUMPS_334
171
145
SUBROUTINE DMUMPS_117(N,ALPHA,DX,INCX)
173
147
DOUBLE PRECISION ALPHA,DX(*)
179
END SUBROUTINE DMUMPS_117
206
180
SUBROUTINE DMUMPS_146( MYID, root, N, IROOT,
207
* COMM, IW, LIW, IFREE,
208
* A, LA, PTRAST, PTLUST_S, PTRFAC,
209
* STEP, INFO, LDLT, QR,
210
* WK, LWK, KEEP,KEEP8)
181
& COMM, IW, LIW, IFREE,
182
& A, LA, PTRAST, PTLUST_S, PTRFAC,
183
& STEP, INFO, LDLT, QR,
184
& WK, LWK, KEEP,KEEP8)
212
186
INCLUDE 'dmumps_root.h'
214
188
TYPE ( DMUMPS_ROOT_STRUC ) :: root
215
INTEGER N, IROOT, COMM, LIW, LA, MYID, LWK, LIWK, IFREE
189
INTEGER N, IROOT, COMM, LIW, MYID, LIWK, IFREE
216
192
DOUBLE PRECISION WK( LWK )
217
193
INTEGER KEEP(500)
218
194
INTEGER*8 KEEP8(150)
219
INTEGER PTRAST(KEEP(28)), PTLUST_S(KEEP(28)), PTRFAC(KEEP(28)),
195
INTEGER(8) :: PTRAST(KEEP(28))
196
INTEGER(8) :: PTRFAC(KEEP(28))
197
INTEGER PTLUST_S(KEEP(28)), STEP(N), IW( LIW )
221
198
INTEGER INFO( 2 ), LDLT, QR
222
199
DOUBLE PRECISION A( LA )
223
INTEGER IOLDPS, IAPOS
224
202
INTEGER LOCAL_M, LOCAL_N, LPIV, IERR, allocok,i
225
203
INCLUDE 'mumps_headers.h'
226
204
IF ( .NOT. root%yes ) RETURN
227
205
IF ( KEEP(60) .NE. 0 ) THEN
228
206
IF ((LDLT == 1 .OR. LDLT == 2) .AND. KEEP(60) == 3 ) THEN
229
207
CALL DMUMPS_320( WK, root%MBLOCK,
230
* root%MYROW, root%MYCOL, root%NPROW, root%NPCOL,
231
* root%SCHUR_POINTER(1),
232
* root%SCHUR_LLD, root%SCHUR_NLOC,
233
* root%TOT_ROOT_SIZE, MYID, COMM )
208
& root%MYROW, root%MYCOL, root%NPROW, root%NPCOL,
209
& root%SCHUR_POINTER(1),
210
& root%SCHUR_LLD, root%SCHUR_NLOC,
211
& root%TOT_ROOT_SIZE, MYID, COMM )
254
232
CALL MUMPS_ABORT()
256
234
CALL DESCINIT( root%DESCRIPTOR, root%TOT_ROOT_SIZE,
257
* root%TOT_ROOT_SIZE, root%MBLOCK, root%NBLOCK,
258
* 0, 0, root%CNTXT_BLACS, LOCAL_M, IERR )
235
& root%TOT_ROOT_SIZE, root%MBLOCK, root%NBLOCK,
236
& 0, 0, root%CNTXT_BLACS, LOCAL_M, IERR )
259
237
IF ( LDLT.EQ.2 ) THEN
260
238
IF(root%MBLOCK.NE.root%NBLOCK) THEN
261
239
WRITE(*,*) ' Error: symmetrization only works for'
262
240
WRITE(*,*) ' square block sizes, MBLOCK/NBLOCK=',
263
* root%MBLOCK, root%NBLOCK
241
& root%MBLOCK, root%NBLOCK
264
242
CALL MUMPS_ABORT()
267
* min(root%MBLOCK * root%NBLOCK,root%TOT_ROOT_SIZE*
268
* root%TOT_ROOT_SIZE ) ) THEN
269
WRITE(*,*) 'Not enough workspace for symmetrization.'
245
& int(root%MBLOCK,8) * int(root%NBLOCK,8),
246
& int(root%TOT_ROOT_SIZE,8)* int(root%TOT_ROOT_SIZE,8 )
248
WRITE(*,*) 'Not enough workspace for symmetrization.'
272
251
CALL DMUMPS_320( WK, root%MBLOCK,
273
* root%MYROW, root%MYCOL, root%NPROW, root%NPCOL,
274
* A( IAPOS ), LOCAL_M, LOCAL_N,
275
* root%TOT_ROOT_SIZE, MYID, COMM )
252
& root%MYROW, root%MYCOL, root%NPROW, root%NPCOL,
253
& A( IAPOS ), LOCAL_M, LOCAL_N,
254
& root%TOT_ROOT_SIZE, MYID, COMM )
277
256
IF (LDLT.EQ.0.OR.LDLT.EQ.2) THEN
278
257
CALL PDGETRF( root%TOT_ROOT_SIZE, root%TOT_ROOT_SIZE,
280
* 1, 1, root%DESCRIPTOR, root%IPIV(1), IERR )
259
& 1, 1, root%DESCRIPTOR, root%IPIV(1), IERR )
281
260
IF ( IERR .GT. 0 ) THEN
286
265
CALL PDPOTRF('L',root%TOT_ROOT_SIZE,A(IAPOS),
287
* 1,1,root%DESCRIPTOR,IERR)
266
& 1,1,root%DESCRIPTOR,IERR)
288
267
IF ( IERR .GT. 0 ) THEN
294
273
END SUBROUTINE DMUMPS_146
295
274
SUBROUTINE DMUMPS_556(
296
* N,PIV,FRERE,FILS,NFSIZ,IKEEP,
297
* NCST,KEEP,KEEP8,id)
275
& N,PIV,FRERE,FILS,NFSIZ,IKEEP,
276
& NCST,KEEP,KEEP8,id)
298
277
USE DMUMPS_STRUC_DEF
300
279
TYPE (DMUMPS_STRUC) :: id
400
379
END SUBROUTINE DMUMPS_550
401
380
SUBROUTINE DMUMPS_547(
402
* N,NZ, IRN, ICN, PIV,
403
* NCMP, IW, LW, IPE, LEN, IQ,
405
* IERROR, KEEP,KEEP8, ICNTL)
381
& N,NZ, IRN, ICN, PIV,
382
& NCMP, IW, LW, IPE, LEN, IQ,
384
& IERROR, KEEP,KEEP8, ICNTL)
407
386
INTEGER N,NZ,NCMP,LW,IWFR,IERROR
408
387
INTEGER ICNTL(40),KEEP(500)
542
521
END SUBROUTINE DMUMPS_547
543
522
SUBROUTINE DMUMPS_551(
544
* N, NE, IP, IRN, SCALING,LSC,CPERM, DIAG,
545
* ICNTL, WEIGHT,MARKED,FLAG,
523
& N, NE, IP, IRN, SCALING,LSC,CPERM, DIAG,
524
& ICNTL, WEIGHT,MARKED,FLAG,
548
527
INTEGER N, NE, ICNTL(10), INFO(10),LSC,LWEIGHT
549
528
INTEGER CPERM(N),PIV_OUT(N),IP(N+1),IRN(NE), DIAG(N)
553
532
INTEGER I,J,K,L,CUR_EL,CUR_EL_PATH,CUR_EL_PATH_NEXT,BEST_BEG
554
533
INTEGER L1,L2,PTR_SET1,PTR_SET2,TUP,T22,INTER,MERGE
555
534
DOUBLE PRECISION BEST_SCORE,CUR_VAL,TMP,VAL
556
DOUBLE PRECISION INITSCORE, DMUMPS_UPDATESCORE,
557
* DMUMPS_UPDATE_INVERSE, DMUMPS_METRIC2x2
535
DOUBLE PRECISION INITSCORE, DMUMPS_739,
536
& DMUMPS_740, DMUMPS_741
558
537
LOGICAL VRAI,FAUX,MAX_CARD_DIAG,USE_SCALING
559
538
INTEGER JOB_DEF,DONE
560
539
INTEGER SUM,PROD,STRUCT,MA47,MAGNITUDE
540
DOUBLE PRECISION ZERO,ONE
562
541
PARAMETER (JOB_DEF = 5, DONE = -1,
563
* SUM = 1, PROD = 2, STRUCT=1, MA47=2, MAGNITUDE=3,
564
* VRAI = .TRUE., FAUX = .FALSE.)
542
& SUM = 1, PROD = 2, STRUCT=1, MA47=2, MAGNITUDE=3,
543
& VRAI = .TRUE., FAUX = .FALSE.)
565
544
PARAMETER(ZERO = 0.0D0, ONE = 1.0D0)
566
545
MAX_CARD_DIAG = .TRUE.
620
599
IF(USE_SCALING) THEN
621
600
VAL = -SCALING(CUR_EL_PATH) - SCALING(CUR_EL+N)
623
CUR_VAL = DMUMPS_METRIC2x2(
624
* CUR_EL,CUR_EL_PATH,
625
* IRN(PTR_SET1),IRN(PTR_SET2),
627
* VAL,DIAG,N,FLAG,FAUX,T22)
602
CUR_VAL = DMUMPS_741(
603
& CUR_EL,CUR_EL_PATH,
604
& IRN(PTR_SET1),IRN(PTR_SET2),
606
& VAL,DIAG,N,FLAG,FAUX,T22)
628
607
WEIGHT(PATH_LENGTH+1) =
629
* DMUMPS_UPDATESCORE(WEIGHT(1),CUR_VAL,TUP)
608
& DMUMPS_739(WEIGHT(1),CUR_VAL,TUP)
631
610
IF(CUR_EL_PATH .EQ. CUR_EL) EXIT
632
611
PATH_LENGTH = PATH_LENGTH+1
638
617
PTR_SET2 = IP(CUR_EL_PATH_NEXT)
639
618
IF(USE_SCALING) THEN
640
619
VAL = -SCALING(CUR_EL_PATH_NEXT)
641
* - SCALING(CUR_EL_PATH+N)
620
& - SCALING(CUR_EL_PATH+N)
643
CUR_VAL = DMUMPS_METRIC2x2(
644
* CUR_EL_PATH,CUR_EL_PATH_NEXT,
645
* IRN(PTR_SET1),IRN(PTR_SET2),
647
* VAL,DIAG,N,FLAG,VRAI,T22)
622
CUR_VAL = DMUMPS_741(
623
& CUR_EL_PATH,CUR_EL_PATH_NEXT,
624
& IRN(PTR_SET1),IRN(PTR_SET2),
626
& VAL,DIAG,N,FLAG,VRAI,T22)
648
627
WEIGHT(PATH_LENGTH+1) =
649
* DMUMPS_UPDATESCORE(WEIGHT(PATH_LENGTH-1),CUR_VAL,TUP)
628
& DMUMPS_739(WEIGHT(PATH_LENGTH-1),CUR_VAL,TUP)
650
629
CUR_EL_PATH = CUR_EL_PATH_NEXT
652
631
IF(mod(PATH_LENGTH,2) .EQ. 1) THEN
683
662
BEST_SCORE = WEIGHT(PATH_LENGTH-1)
684
663
CUR_EL_PATH = CPERM(CUR_EL)
685
664
DO I=1,(PATH_LENGTH/2)-1
686
TMP = DMUMPS_UPDATESCORE(WEIGHT(PATH_LENGTH),
688
TMP = DMUMPS_UPDATE_INVERSE(TMP,WEIGHT(2*I),TUP)
665
TMP = DMUMPS_739(WEIGHT(PATH_LENGTH),
667
TMP = DMUMPS_740(TMP,WEIGHT(2*I),TUP)
689
668
IF(TMP .GT. BEST_SCORE) THEN
691
670
BEST_BEG = CUR_EL_PATH
693
672
CUR_EL_PATH = CPERM(CUR_EL_PATH)
694
TMP = DMUMPS_UPDATESCORE(WEIGHT(PATH_LENGTH+1),
696
TMP = DMUMPS_UPDATE_INVERSE(TMP,WEIGHT(2*I+1),TUP)
673
TMP = DMUMPS_739(WEIGHT(PATH_LENGTH+1),
675
TMP = DMUMPS_740(TMP,WEIGHT(2*I+1),TUP)
697
676
IF(TMP .GT. BEST_SCORE) THEN
699
678
BEST_BEG = CUR_EL_PATH
732
711
END SUBROUTINE DMUMPS_551
733
FUNCTION DMUMPS_UPDATESCORE(A,B,T)
735
DOUBLE PRECISION DMUMPS_UPDATESCORE
739
PARAMETER(SUM = 1,PROD = 2)
741
DMUMPS_UPDATESCORE = A+B
743
DMUMPS_UPDATESCORE = A*B
745
END FUNCTION DMUMPS_UPDATESCORE
746
FUNCTION DMUMPS_UPDATE_INVERSE(A,B,T)
748
DOUBLE PRECISION DMUMPS_UPDATE_INVERSE
752
PARAMETER(SUM = 1,PROD = 2)
754
DMUMPS_UPDATE_INVERSE = A-B
756
DMUMPS_UPDATE_INVERSE = A/B
758
END FUNCTION DMUMPS_UPDATE_INVERSE
759
FUNCTION DMUMPS_METRIC2x2(CUR_EL,CUR_EL_PATH,
760
* SET1,SET2,L1,L2,VAL,DIAG,N,FLAG,FLAGON,T)
762
DOUBLE PRECISION DMUMPS_METRIC2x2
712
FUNCTION DMUMPS_739(A,B,T)
714
DOUBLE PRECISION DMUMPS_739
718
PARAMETER(SUM = 1,PROD = 2)
724
END FUNCTION DMUMPS_739
725
FUNCTION DMUMPS_740(A,B,T)
727
DOUBLE PRECISION DMUMPS_740
731
PARAMETER(SUM = 1,PROD = 2)
737
END FUNCTION DMUMPS_740
738
FUNCTION DMUMPS_741(CUR_EL,CUR_EL_PATH,
739
& SET1,SET2,L1,L2,VAL,DIAG,N,FLAG,FLAGON,T)
741
DOUBLE PRECISION DMUMPS_741
763
742
INTEGER CUR_EL,CUR_EL_PATH,L1,L2,N
764
743
INTEGER SET1(L1),SET2(L2),DIAG(N),FLAG(N)
765
744
DOUBLE PRECISION VAL
784
763
MERGE = L1 + L2 - INTER
785
DMUMPS_METRIC2x2 = dble(INTER) / dble(MERGE)
764
DMUMPS_741 = dble(INTER) / dble(MERGE)
786
765
ELSE IF (T .EQ. MA47) THEN
788
767
IF(DIAG(CUR_EL) .NE. 0) MERGE = 2
789
768
IF(DIAG(CUR_EL_PATH) .NE. 0) MERGE = MERGE - 2
790
769
IF(MERGE .EQ. 0) THEN
791
DMUMPS_METRIC2x2 = L1+L2-2
792
DMUMPS_METRIC2x2 = -(DMUMPS_METRIC2x2**2)/2
770
DMUMPS_741 = dble(L1+L2-2)
771
DMUMPS_741 = -(DMUMPS_741**2)/2.0D0
793
772
ELSE IF(MERGE .EQ. 1) THEN
794
DMUMPS_METRIC2x2 = - dble(L1+L2-4) * dble(L1-2)
773
DMUMPS_741 = - dble(L1+L2-4) * dble(L1-2)
795
774
ELSE IF(MERGE .EQ. 2) THEN
796
DMUMPS_METRIC2x2 = - dble(L1+L2-4) * dble(L2-2)
775
DMUMPS_741 = - dble(L1+L2-4) * dble(L2-2)
798
DMUMPS_METRIC2x2 = - dble(L1-2) * dble(L2-2)
777
DMUMPS_741 = - dble(L1-2) * dble(L2-2)
801
DMUMPS_METRIC2x2 = VAL
805
784
SUBROUTINE DMUMPS_622(NA, NCMP,
807
* LISTVAR_SCHUR, SIZE_SCHUR, AOTOA)
786
& LISTVAR_SCHUR, SIZE_SCHUR, AOTOA)
809
788
INTEGER, INTENT(IN):: SIZE_SCHUR, LISTVAR_SCHUR(SIZE_SCHUR)
810
789
INTEGER, INTENT(IN):: NA, NCMP
825
804
END SUBROUTINE DMUMPS_622
826
805
SUBROUTINE DMUMPS_623
827
* (NA,N,NZ, IRN, ICN, IW, LW, IPE, LEN,
829
* NRORM, NIORM, IFLAG,IERROR, ICNTL,
830
* symmetry, SYM, MedDens, NBQD, AvgDens,
831
* LISTVAR_SCHUR, SIZE_SCHUR, ATOAO, AOTOA)
806
& (NA,N,NZ, IRN, ICN, IW, LW, IPE, LEN,
808
& NRORM, NIORM, IFLAG,IERROR, ICNTL,
809
& symmetry, SYM, MedDens, NBQD, AvgDens,
810
& LISTVAR_SCHUR, SIZE_SCHUR, ATOAO, AOTOA)
833
812
INTEGER, INTENT(IN) :: NA,N,NZ,LW
834
813
INTEGER, INTENT(IN) :: SIZE_SCHUR, LISTVAR_SCHUR(SIZE_SCHUR)
835
814
INTEGER, INTENT(IN) :: IRN(NZ), ICN(NZ)
836
815
INTEGER, INTENT(IN) :: ICNTL(40), SYM
837
INTEGER, INTENT(OUT) :: IFLAG,IERROR,NRORM,NIORM,IWFR
816
INTEGER, INTENT(INOUT) :: IFLAG
817
INTEGER, INTENT(OUT) :: IERROR,NRORM,NIORM,IWFR
838
818
INTEGER, INTENT(OUT) :: AOTOA(N)
839
819
INTEGER, INTENT(OUT) :: ATOAO(NA)
840
820
INTEGER, INTENT(OUT) :: LEN(N), IPE(N+1)
895
875
IF ((I.GT.NA).OR.(J.GT.NA).OR.(I.LT.1)
897
877
NBERR = NBERR + 1
898
878
IF (NBERR.LE.10) THEN
899
879
IF (mod(K,10).GT.3 .OR. mod(K,10).EQ.0 .OR.
900
* (10.LE.K .AND. K.LE.20)) THEN
880
& (10.LE.K .AND. K.LE.20)) THEN
901
881
WRITE (MP,'(I8,A,I8,A,I8,A)')
902
* K,'th entry (in row',I,' and column',J,') ignored'
882
& K,'th entry (in row',I,' and column',J,') ignored'
904
884
IF (mod(K,10).EQ.1) WRITE(MP,'(I8,A,I8,A,I8,A)')
905
* K,'st entry (in row',I,' and column',J,') ignored'
885
& K,'st entry (in row',I,' and column',J,') ignored'
906
886
IF (mod(K,10).EQ.2) WRITE(MP,'(I8,A,I8,A,I8,A)')
907
* K,'nd entry (in row',I,' and column',J,') ignored'
887
& K,'nd entry (in row',I,' and column',J,') ignored'
908
888
IF (mod(K,10).EQ.3) WRITE(MP,'(I8,A,I8,A,I8,A)')
909
* K,'rd entry (in row',I,' and column',J,') ignored'
889
& K,'rd entry (in row',I,' and column',J,') ignored'
1078
1058
END SUBROUTINE DMUMPS_549
1059
SUBROUTINE DMUMPS_548(N,PE,NV,WORK)
1062
INTEGER PE(N),NV(N),WORK(N)
1063
INTEGER I,FATHER,LEN,K,NEWSON,NEWFATHER
1065
IF(NV(I) .GT. 0) CYCLE
1070
IF(NV(FATHER) .GT. 0) THEN
1077
FATHER = -PE(FATHER)
1079
NEWFATHER = -PE(FATHER)
1080
PE(WORK(LEN)) = -NEWFATHER
1081
PE(NEWSON) = -WORK(1)
1083
END SUBROUTINE DMUMPS_548