root / src / minv.f90
Historique | Voir | Annoter | Télécharger (4,58 ko)
1 | 1 | pfleura2 | SUBROUTINE MINV(A,N,D) |
---|---|---|---|
2 | 12 | pfleura2 | |
3 | 12 | pfleura2 | |
4 | 12 | pfleura2 | !---------------------------------------------------------------------- |
5 | 12 | pfleura2 | ! This routine was adapted from the public domain mopac6 diis.f |
6 | 12 | pfleura2 | ! source file (c) 2009, Stewart Computational Chemistry. |
7 | 12 | pfleura2 | ! <http://www.openmopac.net/Downloads/Downloads.html> |
8 | 12 | pfleura2 | ! |
9 | 12 | pfleura2 | !---------------------------------------------------------------------- |
10 | 12 | pfleura2 | ! Copyright 2003-2014 Ecole Normale Supérieure de Lyon, |
11 | 12 | pfleura2 | ! Centre National de la Recherche Scientifique, |
12 | 12 | pfleura2 | ! Université Claude Bernard Lyon 1. All rights reserved. |
13 | 12 | pfleura2 | ! |
14 | 12 | pfleura2 | ! This work is registered with the Agency for the Protection of Programs |
15 | 12 | pfleura2 | ! as IDDN.FR.001.100009.000.S.P.2014.000.30625 |
16 | 12 | pfleura2 | ! |
17 | 12 | pfleura2 | ! Authors: P. Fleurat-Lessard, P. Dayal |
18 | 12 | pfleura2 | ! Contact: optnpath@gmail.com |
19 | 12 | pfleura2 | ! |
20 | 12 | pfleura2 | ! This file is part of "Opt'n Path". |
21 | 12 | pfleura2 | ! |
22 | 12 | pfleura2 | ! "Opt'n Path" is free software: you can redistribute it and/or modify |
23 | 12 | pfleura2 | ! it under the terms of the GNU Affero General Public License as |
24 | 12 | pfleura2 | ! published by the Free Software Foundation, either version 3 of the License, |
25 | 12 | pfleura2 | ! or (at your option) any later version. |
26 | 12 | pfleura2 | ! |
27 | 12 | pfleura2 | ! "Opt'n Path" is distributed in the hope that it will be useful, |
28 | 12 | pfleura2 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | 12 | pfleura2 | ! |
30 | 12 | pfleura2 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | 12 | pfleura2 | ! GNU Affero General Public License for more details. |
32 | 12 | pfleura2 | ! |
33 | 12 | pfleura2 | ! You should have received a copy of the GNU Affero General Public License |
34 | 12 | pfleura2 | ! along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>. |
35 | 12 | pfleura2 | ! |
36 | 12 | pfleura2 | ! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr, |
37 | 12 | pfleura2 | ! for commercial licensing opportunities. |
38 | 12 | pfleura2 | !---------------------------------------------------------------------- |
39 | 1 | pfleura2 | |
40 | 12 | pfleura2 | |
41 | 1 | pfleura2 | IMPLICIT NONE |
42 | 1 | pfleura2 | integer, parameter :: KINT = kind(1) |
43 | 1 | pfleura2 | integer, parameter :: KREAL = kind(1.0d0) |
44 | 1 | pfleura2 | |
45 | 3 | pfleura2 | INTEGER(KINT), INTENT(IN) :: N |
46 | 1 | pfleura2 | REAL(KREAL), INTENT(INOUT) :: A(N*N) |
47 | 1 | pfleura2 | REAL(KREAL), INTENT(OUT) :: D |
48 | 1 | pfleura2 | |
49 | 1 | pfleura2 | |
50 | 1 | pfleura2 | !********************************************************************** |
51 | 1 | pfleura2 | !* |
52 | 1 | pfleura2 | !* INVERT A MATRIX USING GAUSS-JORDAN METHOD. PART OF DIIS |
53 | 1 | pfleura2 | !* A - INPUT MATRIX (MUST BE A GENERAL MATRIX), DESTROYED IN |
54 | 1 | pfleura2 | !* COMPUTATION AND REPLACED BY RESULTANT INVERSE. |
55 | 1 | pfleura2 | !* N - ORDER OF MATRIX A |
56 | 1 | pfleura2 | !* D - RESULTANT DETERMINANT |
57 | 1 | pfleura2 | !* |
58 | 1 | pfleura2 | !********************************************************************** |
59 | 1 | pfleura2 | INTEGER(KINT), ALLOCATABLE :: L(:), M(:) |
60 | 1 | pfleura2 | INTEGER(KINT) :: I,J,K,NK,KK,KI,KJ,IZ,IJ,JP,JK,IK,JR,JQ,JI |
61 | 1 | pfleura2 | |
62 | 1 | pfleura2 | REAL(KREAL) :: BigA,Hold |
63 | 1 | pfleura2 | |
64 | 1 | pfleura2 | ALLOCATE(L(N),M(N)) |
65 | 1 | pfleura2 | ! |
66 | 1 | pfleura2 | ! SEARCH FOR LARGEST ELEMENT |
67 | 1 | pfleura2 | ! |
68 | 1 | pfleura2 | D=1.0D0 |
69 | 1 | pfleura2 | NK=-N |
70 | 1 | pfleura2 | DO 180 K=1,N |
71 | 1 | pfleura2 | NK=NK+N |
72 | 1 | pfleura2 | L(K)=K |
73 | 1 | pfleura2 | M(K)=K |
74 | 1 | pfleura2 | KK=NK+K |
75 | 1 | pfleura2 | BIGA=A(KK) |
76 | 1 | pfleura2 | DO 20 J=K,N |
77 | 1 | pfleura2 | IZ=N*(J-1) |
78 | 1 | pfleura2 | DO 20 I=K,N |
79 | 1 | pfleura2 | IJ=IZ+I |
80 | 2 | pfleura2 | IF (ABS(BIGA).LT.ABS(A(IJ)))THEN |
81 | 1 | pfleura2 | BIGA=A(IJ) |
82 | 1 | pfleura2 | L(K)=I |
83 | 1 | pfleura2 | M(K)=J |
84 | 1 | pfleura2 | ENDIF |
85 | 2 | pfleura2 | 20 CONTINUE |
86 | 1 | pfleura2 | ! |
87 | 1 | pfleura2 | ! INTERCHANGE ROWS |
88 | 1 | pfleura2 | ! |
89 | 1 | pfleura2 | J=L(K) |
90 | 1 | pfleura2 | IF (J-K) 50,50,30 |
91 | 1 | pfleura2 | 30 KI=K-N |
92 | 1 | pfleura2 | DO 40 I=1,N |
93 | 1 | pfleura2 | KI=KI+N |
94 | 1 | pfleura2 | HOLD=-A(KI) |
95 | 1 | pfleura2 | JI=KI-K+J |
96 | 1 | pfleura2 | A(KI)=A(JI) |
97 | 1 | pfleura2 | 40 A(JI)=HOLD |
98 | 1 | pfleura2 | ! |
99 | 1 | pfleura2 | ! INTERCHANGE COLUMNS |
100 | 1 | pfleura2 | ! |
101 | 1 | pfleura2 | 50 I=M(K) |
102 | 1 | pfleura2 | IF (I-K) 80,80,60 |
103 | 1 | pfleura2 | 60 JP=N*(I-1) |
104 | 1 | pfleura2 | DO 70 J=1,N |
105 | 1 | pfleura2 | JK=NK+J |
106 | 1 | pfleura2 | JI=JP+J |
107 | 1 | pfleura2 | HOLD=-A(JK) |
108 | 1 | pfleura2 | A(JK)=A(JI) |
109 | 1 | pfleura2 | 70 A(JI)=HOLD |
110 | 1 | pfleura2 | !C |
111 | 1 | pfleura2 | !C DIVIDE COLUMN BY MINUS PIVOT (VALUE OF PIVOT ELEMENT IS |
112 | 1 | pfleura2 | !C CONTAINED IN BIGA) |
113 | 1 | pfleura2 | !C |
114 | 1 | pfleura2 | 80 IF (BIGA) 100,90,100 |
115 | 1 | pfleura2 | 90 D=0.0 |
116 | 1 | pfleura2 | RETURN |
117 | 1 | pfleura2 | 100 DO 120 I=1,N |
118 | 1 | pfleura2 | IF (I-K) 110,120,110 |
119 | 1 | pfleura2 | 110 IK=NK+I |
120 | 1 | pfleura2 | A(IK)=A(IK)/(-BIGA) |
121 | 1 | pfleura2 | 120 CONTINUE |
122 | 1 | pfleura2 | !C REDUCE MATRIX |
123 | 1 | pfleura2 | DO 150 I=1,N |
124 | 1 | pfleura2 | IK=NK+I |
125 | 1 | pfleura2 | HOLD=A(IK) |
126 | 1 | pfleura2 | IJ=I-N |
127 | 1 | pfleura2 | DO 150 J=1,N |
128 | 1 | pfleura2 | IJ=IJ+N |
129 | 1 | pfleura2 | IF (I-K) 130,150,130 |
130 | 1 | pfleura2 | 130 IF (J-K) 140,150,140 |
131 | 1 | pfleura2 | 140 KJ=IJ-I+K |
132 | 1 | pfleura2 | A(IJ)=HOLD*A(KJ)+A(IJ) |
133 | 1 | pfleura2 | 150 CONTINUE |
134 | 1 | pfleura2 | !C |
135 | 1 | pfleura2 | !C DIVIDE ROW BY PIVOT |
136 | 1 | pfleura2 | !C |
137 | 1 | pfleura2 | KJ=K-N |
138 | 1 | pfleura2 | DO 170 J=1,N |
139 | 1 | pfleura2 | KJ=KJ+N |
140 | 1 | pfleura2 | IF (J-K) 160,170,160 |
141 | 1 | pfleura2 | 160 A(KJ)=A(KJ)/BIGA |
142 | 1 | pfleura2 | 170 CONTINUE |
143 | 1 | pfleura2 | !C |
144 | 1 | pfleura2 | !C PRODUCT OF PIVOTS |
145 | 1 | pfleura2 | !C |
146 | 1 | pfleura2 | D=MAX(-1.D25,MIN(1.D25,D)) |
147 | 1 | pfleura2 | D=D*BIGA |
148 | 1 | pfleura2 | !C |
149 | 1 | pfleura2 | !C REPLACE PIVOT BY RECIPROCAL |
150 | 1 | pfleura2 | !C |
151 | 1 | pfleura2 | A(KK)=1.0/BIGA |
152 | 1 | pfleura2 | 180 CONTINUE |
153 | 1 | pfleura2 | !C |
154 | 1 | pfleura2 | !C FINAL ROW AND COLUMN INTERCHANGE |
155 | 1 | pfleura2 | !C |
156 | 1 | pfleura2 | K=N |
157 | 1 | pfleura2 | 190 K=(K-1) |
158 | 1 | pfleura2 | IF (K) 260,260,200 |
159 | 1 | pfleura2 | 200 I=L(K) |
160 | 1 | pfleura2 | IF (I-K) 230,230,210 |
161 | 1 | pfleura2 | 210 JQ=N*(K-1) |
162 | 1 | pfleura2 | JR=N*(I-1) |
163 | 1 | pfleura2 | DO 220 J=1,N |
164 | 1 | pfleura2 | JK=JQ+J |
165 | 1 | pfleura2 | HOLD=A(JK) |
166 | 1 | pfleura2 | JI=JR+J |
167 | 1 | pfleura2 | A(JK)=-A(JI) |
168 | 1 | pfleura2 | 220 A(JI)=HOLD |
169 | 1 | pfleura2 | 230 J=M(K) |
170 | 1 | pfleura2 | IF (J-K) 190,190,240 |
171 | 1 | pfleura2 | 240 KI=K-N |
172 | 1 | pfleura2 | DO 250 I=1,N |
173 | 1 | pfleura2 | KI=KI+N |
174 | 1 | pfleura2 | HOLD=A(KI) |
175 | 1 | pfleura2 | JI=KI-K+J |
176 | 1 | pfleura2 | A(KI)=-A(JI) |
177 | 1 | pfleura2 | 250 A(JI) =HOLD |
178 | 1 | pfleura2 | GO TO 190 |
179 | 1 | pfleura2 | 260 RETURN |
180 | 1 | pfleura2 | END |