root / src / Egrad.f90 @ 1
Historique | Voir | Annoter | Télécharger (15,22 ko)
1 | 1 | pfleura2 | subroutine Egrad(E,Geom,Grad,NCoord,IGeom,IOpt,GeomCart,FOptGeom,GeomOld,GeomCart_old) |
---|---|---|---|
2 | 1 | pfleura2 | |
3 | 1 | pfleura2 | ! This routines calculates the energy E and the gradient Grad of |
4 | 1 | pfleura2 | ! a molecule with Geometry Geom (may be in internal coordinates), |
5 | 1 | pfleura2 | ! using for now, either Gaussian or Ext, more general later. |
6 | 1 | pfleura2 | |
7 | 1 | pfleura2 | use Path_module, only : Nat,AtName,Coord,dzdc,indzmat,Nom,Atome,massat,unit, & |
8 | 1 | pfleura2 | prog,NCart,XyzGeomF,IntCoordF,BTransInv, XyzGeomI, renum, & |
9 | 1 | pfleura2 | GeomOld_all,BTransInvF,BTransInv_local,UMatF,UMat_local & |
10 | 1 | pfleura2 | , BprimT,a0,ScanCoord, Coordinate,NPrim,BMat_BakerT,BBT,BBT_inv & |
11 | 1 | pfleura2 | , Order,OrderInv, XPrimitiveF |
12 | 1 | pfleura2 | |
13 | 1 | pfleura2 | ! IntCoordF(NGeomF,NCoord),GeomOld_all(NGeomF,NCoord) |
14 | 1 | pfleura2 | ! allocated in Path.f90 |
15 | 1 | pfleura2 | |
16 | 1 | pfleura2 | use Io_module |
17 | 1 | pfleura2 | IMPLICIT NONE |
18 | 1 | pfleura2 | |
19 | 1 | pfleura2 | ! Energy (calculated if F300K=.F., else estimated) |
20 | 1 | pfleura2 | REAL(KREAL), INTENT (OUT) :: E |
21 | 1 | pfleura2 | ! NCoord: Number of the degrees of freedom |
22 | 1 | pfleura2 | ! IGeom: index of the geometry. |
23 | 1 | pfleura2 | INTEGER(KINT), INTENT (IN) :: NCoord, IGeom, IOpt |
24 | 1 | pfleura2 | ! Geometry at which gradient is calculated (cf Factual also): |
25 | 1 | pfleura2 | REAL(KREAL), INTENT (INOUT) :: Geom(NCoord) |
26 | 1 | pfleura2 | ! Gradient calculated at Geom geometry: |
27 | 1 | pfleura2 | REAL(KREAL), INTENT (OUT) :: Grad(NCoord) |
28 | 1 | pfleura2 | ! Cartesian geometry corresponding to (Internal Geometry) Geom: |
29 | 1 | pfleura2 | REAL(KREAL), INTENT (OUT) :: GeomCart(Nat,3) |
30 | 1 | pfleura2 | !!! Optional, just for geometry optimization with Baker coordinates |
31 | 1 | pfleura2 | REAL(KREAL), INTENT (IN), OPTIONAL :: GeomCart_old(Nat,3) |
32 | 1 | pfleura2 | REAL(KREAL), INTENT (INOUT), OPTIONAL :: GeomOld(NCoord) |
33 | 1 | pfleura2 | ! FOptGeom is a flag indicating if we are doing a geom optimization |
34 | 1 | pfleura2 | ! it can be omitted so that we use a local flag: Flag_Opt_Geom |
35 | 1 | pfleura2 | LOGICAL,INTENT (IN), OPTIONAL :: FOptGeom |
36 | 1 | pfleura2 | ! if FOptGeom is given Flag_Opt_Geom=FOptGeom, else Flag_Opt_Geom=F |
37 | 1 | pfleura2 | LOGICAL :: Flag_Opt_Geom |
38 | 1 | pfleura2 | |
39 | 1 | pfleura2 | ! ====================================================================== |
40 | 1 | pfleura2 | |
41 | 1 | pfleura2 | LOGICAL :: debug |
42 | 1 | pfleura2 | REAL(KREAL), ALLOCATABLE :: GradTmp(:) |
43 | 1 | pfleura2 | REAL(KREAL), ALLOCATABLE :: GradCart(:) |
44 | 1 | pfleura2 | REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:) |
45 | 1 | pfleura2 | REAL(KREAL) :: Pi |
46 | 1 | pfleura2 | |
47 | 1 | pfleura2 | INTEGER(KINT) :: iat, i, j, IBeg,Idx |
48 | 1 | pfleura2 | INTEGER(KINT), PARAMETER :: IOLOG=12, IOCOM=11 |
49 | 1 | pfleura2 | |
50 | 1 | pfleura2 | INTEGER(KINT), PARAMETER :: NbExtName=4 |
51 | 1 | pfleura2 | |
52 | 1 | pfleura2 | REAL(KREAL), ALLOCATABLE :: XPrimRef(:), XPrim(:) ! NPrim |
53 | 1 | pfleura2 | |
54 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
55 | 1 | pfleura2 | ! |
56 | 1 | pfleura2 | !!!!!!!! PFL Debug |
57 | 1 | pfleura2 | ! |
58 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
59 | 1 | pfleura2 | REAL(KREAL), ALLOCATABLE :: GeomTmp(:,:) !3,Nat |
60 | 1 | pfleura2 | LOGICAL :: FALOBBT,FALOBPrimt,FAloBBTInv |
61 | 1 | pfleura2 | LOGICAL :: DebugPFL |
62 | 1 | pfleura2 | |
63 | 1 | pfleura2 | ! ====================================================================== |
64 | 1 | pfleura2 | INTERFACE |
65 | 1 | pfleura2 | function valid(string) result (isValid) |
66 | 1 | pfleura2 | CHARACTER(*), intent(in) :: string |
67 | 1 | pfleura2 | logical :: isValid |
68 | 1 | pfleura2 | END function VALID |
69 | 1 | pfleura2 | END INTERFACE |
70 | 1 | pfleura2 | ! ====================================================================== |
71 | 1 | pfleura2 | |
72 | 1 | pfleura2 | Pi=dacos(-1.0d0) |
73 | 1 | pfleura2 | |
74 | 1 | pfleura2 | if (present(FOptGeom)) THEN |
75 | 1 | pfleura2 | Flag_Opt_Geom=FOptGeom |
76 | 1 | pfleura2 | ELSE |
77 | 1 | pfleura2 | Flag_Opt_Geom=.FALSE. |
78 | 1 | pfleura2 | END IF |
79 | 1 | pfleura2 | |
80 | 1 | pfleura2 | debug=valid('EGRAD') |
81 | 1 | pfleura2 | debugPFL=valid('bakerPFL') |
82 | 1 | pfleura2 | if (debug) Call Header("Entering Egrad") |
83 | 1 | pfleura2 | |
84 | 1 | pfleura2 | if (debug) Print *, 'EGrad.f90, L73, IOpt=', IOpt, ' Flag_Opt_Geom=',Flag_Opt_Geom |
85 | 1 | pfleura2 | |
86 | 1 | pfleura2 | Grad=0. |
87 | 1 | pfleura2 | E=0. |
88 | 1 | pfleura2 | |
89 | 1 | pfleura2 | |
90 | 1 | pfleura2 | ALLOCATE(GradCart(3*Nat)) |
91 | 1 | pfleura2 | ALLOCATE(x(Nat),y(Nat),z(Nat)) |
92 | 1 | pfleura2 | ALLOCATE(XPrimRef(NPrim),XPrim(NPrim)) |
93 | 1 | pfleura2 | |
94 | 1 | pfleura2 | SELECT CASE (COORD) |
95 | 1 | pfleura2 | CASE ('ZMAT') |
96 | 1 | pfleura2 | ! In order to avoid problem with numbering and linear angles/diehedral, we convert the |
97 | 1 | pfleura2 | ! zmat into cartesian coordinates |
98 | 1 | pfleura2 | ! A remplacer par Int2Cart :-) |
99 | 1 | pfleura2 | Call Int2Cart(nat,indzmat,Geom,GeomCart) |
100 | 1 | pfleura2 | CASE ('BAKER') |
101 | 1 | pfleura2 | XPrimRef=XPrimitiveF(IGeom,:) |
102 | 1 | pfleura2 | IF (Flag_Opt_Geom) THEN |
103 | 1 | pfleura2 | IF (IOpt .EQ. 1) THEN |
104 | 1 | pfleura2 | GeomCart(:,1) = XyzGeomI(IGeom,1,:) |
105 | 1 | pfleura2 | GeomCart(:,2) = XyzGeomI(IGeom,2,:) |
106 | 1 | pfleura2 | GeomCart(:,3) = XyzGeomI(IGeom,3,:) |
107 | 1 | pfleura2 | ELSE |
108 | 1 | pfleura2 | if (debug) WRITE(*,*) 'Before Call ConvertBakerInternal_cart; L125, Egrad.f90' |
109 | 1 | pfleura2 | if (.NOT.present(GeomOld)) THEN |
110 | 1 | pfleura2 | WRITE(*,*) "ERROR: GeomOld not passed as an argument" |
111 | 1 | pfleura2 | STOP |
112 | 1 | pfleura2 | END IF |
113 | 1 | pfleura2 | WRITE(*,*) 'GeomOld=' |
114 | 1 | pfleura2 | WRITE(*,'(12(1X,F6.3))') GeomOld |
115 | 1 | pfleura2 | WRITE(*,*) 'Geom=' |
116 | 1 | pfleura2 | WRITE(*,'(12(1X,F6.3))') Geom |
117 | 1 | pfleura2 | if (.NOT.present(GeomCart_Old)) THEN |
118 | 1 | pfleura2 | WRITE(*,*) "ERROR: GeomCart_Old not passed as an argument" |
119 | 1 | pfleura2 | STOP |
120 | 1 | pfleura2 | END IF |
121 | 1 | pfleura2 | |
122 | 1 | pfleura2 | WRITE(*,*) 'GeomCart_old=' |
123 | 1 | pfleura2 | WRITE(*,'(20(1X,F6.3))') GeomCart_old(1:Nat,1:3) |
124 | 1 | pfleura2 | Call ConvertBakerInternal_cart(GeomOld,Geom,GeomCart_old(:,1), & |
125 | 1 | pfleura2 | GeomCart_old(:,2),GeomCart_old(:,3),x,y,z,XPrim,XPrimRef) |
126 | 1 | pfleura2 | GeomCart(:,1) = x(:) |
127 | 1 | pfleura2 | GeomCart(:,2) = y(:) |
128 | 1 | pfleura2 | GeomCart(:,3) = z(:) |
129 | 1 | pfleura2 | END IF |
130 | 1 | pfleura2 | ELSE |
131 | 1 | pfleura2 | IF (IOpt .EQ. 0) THEN |
132 | 1 | pfleura2 | GeomCart(:,1) = XyzGeomF(IGeom,1,:) |
133 | 1 | pfleura2 | GeomCart(:,2) = XyzGeomF(IGeom,2,:) |
134 | 1 | pfleura2 | GeomCart(:,3) = XyzGeomF(IGeom,3,:) |
135 | 1 | pfleura2 | ELSE |
136 | 1 | pfleura2 | ! IntCoordF(NGeomF,NCoord), XyzGeomF(NGeomF,3,Nat) |
137 | 1 | pfleura2 | ! Geom has to be converted into x,y,z |
138 | 1 | pfleura2 | ! GeomOld_all and XyzGeomF are old geometry in internal and cartesian coords resp. |
139 | 1 | pfleura2 | DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart() |
140 | 1 | pfleura2 | BTransInv_local(I,:) = BTransInvF(IGeom,I,:) |
141 | 1 | pfleura2 | UMat_local(:,I) = UMatF(IGeom,:,I) |
142 | 1 | pfleura2 | END DO |
143 | 1 | pfleura2 | if (debug) Print *, 'I am before Call ConvertBakerInternal_cart; L160, Egrad.f90' |
144 | 1 | pfleura2 | WRITE(*,*) 'GeomOld=' |
145 | 1 | pfleura2 | WRITE(*,'(12(1X,F6.3))') GeomOld_all(IGeom,:) |
146 | 1 | pfleura2 | WRITE(*,*) 'Geom=' |
147 | 1 | pfleura2 | WRITE(*,'(12(1X,F6.3))') Geom |
148 | 1 | pfleura2 | WRITE(*,*) 'DBG Egrad L165 GeomCart_old=' |
149 | 1 | pfleura2 | DO I=1,Nat |
150 | 1 | pfleura2 | WRITE(*,'(3(1X,F12.8))') XyzGeomF(IGeom,:,I) |
151 | 1 | pfleura2 | END DO |
152 | 1 | pfleura2 | |
153 | 1 | pfleura2 | Call ConvertBakerInternal_cart(GeomOld_all(IGeom,:),Geom,XyzGeomF(IGeom,1,:), & |
154 | 1 | pfleura2 | XyzGeomF(IGeom,2,:),XyzGeomF(IGeom,3,:),x,y,z,XPrim,XPrimRef) |
155 | 1 | pfleura2 | if (debug) Print *, 'I am after Call ConvertBakerInternal_cart; L111, Egrad.f90' |
156 | 1 | pfleura2 | DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart() |
157 | 1 | pfleura2 | BTransInvF(IGeom,I,:) = BTransInv_local(I,:) |
158 | 1 | pfleura2 | END DO |
159 | 1 | pfleura2 | ! GeomCart is actually XyzCoord and has INTENT(OUT) in this subroutine. |
160 | 1 | pfleura2 | GeomCart(:,1) = x(:) |
161 | 1 | pfleura2 | GeomCart(:,2) = y(:) |
162 | 1 | pfleura2 | GeomCart(:,3) = z(:) |
163 | 1 | pfleura2 | END IF ! matches IF (IOpt .EQ. 0) THEN |
164 | 1 | pfleura2 | END IF |
165 | 1 | pfleura2 | CASE ('MIXED') |
166 | 1 | pfleura2 | ! write(*,*) "Coucou 4-mixed" |
167 | 1 | pfleura2 | Call Mixed2Cart(Nat,indzmat,geom,GeomCart) |
168 | 1 | pfleura2 | CASE ('CART') |
169 | 1 | pfleura2 | ! write(*,*) "Coucou 4-cart" |
170 | 1 | pfleura2 | if (debug) WRITE(*,*) "Coord=CART... in egrad" |
171 | 1 | pfleura2 | GeomCart=reshape(Geom,(/Nat,3/)) |
172 | 1 | pfleura2 | DO Iat=1,Nat |
173 | 1 | pfleura2 | WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),Geom(3*Iat-2:3*Iat) |
174 | 1 | pfleura2 | END DO |
175 | 1 | pfleura2 | CASE ('HYBRID') |
176 | 1 | pfleura2 | ! write(*,*) "Coucou 4-hybrid" |
177 | 1 | pfleura2 | GeomCart=reshape(Geom,(/Nat,3/)) |
178 | 1 | pfleura2 | CASE DEFAULT |
179 | 1 | pfleura2 | WRITE (*,*) "Coord=",TRIM(COORD)," not recognized. Stop" |
180 | 1 | pfleura2 | STOP |
181 | 1 | pfleura2 | END SELECT |
182 | 1 | pfleura2 | !WRITE(*,*) Nat |
183 | 1 | pfleura2 | !WRITE(*,*) 'GeomCart in Egrad_baker' |
184 | 1 | pfleura2 | !DO I=1,Nat |
185 | 1 | pfleura2 | ! WRITE(*,'(1X,A,3(1X,F12.8))') AtName(I),GeomCart(I,1:3) |
186 | 1 | pfleura2 | !END DO |
187 | 1 | pfleura2 | |
188 | 1 | pfleura2 | SELECT CASE (Prog) |
189 | 1 | pfleura2 | CASE ('GAUSSIAN') |
190 | 1 | pfleura2 | ! we call the Gaussian routine. |
191 | 1 | pfleura2 | ! it will return the energy and the gradient in cartesian coordinates. |
192 | 1 | pfleura2 | ! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT) |
193 | 1 | pfleura2 | Call egrad_gaussian(E,GeomCart,GradCart) |
194 | 1 | pfleura2 | CASE ('MOPAC') |
195 | 1 | pfleura2 | ! we call the Mopac routine. |
196 | 1 | pfleura2 | ! it will return the energy and the gradient in cartesian coordinates. |
197 | 1 | pfleura2 | ! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT) |
198 | 1 | pfleura2 | Call egrad_mopac(E,GeomCart,GradCart) |
199 | 1 | pfleura2 | CASE ('VASP') |
200 | 1 | pfleura2 | Call egrad_vasp(E,Geomcart,GradCart) |
201 | 1 | pfleura2 | CASE ('TURBOMOLE') |
202 | 1 | pfleura2 | Call egrad_turbomole(E,Geomcart,GradCart) |
203 | 1 | pfleura2 | CASE ('EXT') |
204 | 1 | pfleura2 | Call egrad_ext(E,Geomcart,GradCart) |
205 | 1 | pfleura2 | CASE ('TEST') |
206 | 1 | pfleura2 | Call egrad_test(Nat,E,Geomcart,GradCart) |
207 | 1 | pfleura2 | CASE ('CHAMFRE') |
208 | 1 | pfleura2 | Call egrad_chamfre(Nat,E,Geomcart,GradCart) |
209 | 1 | pfleura2 | END SELECT |
210 | 1 | pfleura2 | if (debug) THEN |
211 | 1 | pfleura2 | WRITE(*,*) 'DBG EGRAD, GradCart read' |
212 | 1 | pfleura2 | DO I=1,Nat |
213 | 1 | pfleura2 | Iat=I |
214 | 1 | pfleura2 | if (renum) Iat=orderInv(I) |
215 | 1 | pfleura2 | WRITE(*,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),GradCart(3*I-2:3*I) |
216 | 1 | pfleura2 | END DO |
217 | 1 | pfleura2 | END IF |
218 | 1 | pfleura2 | |
219 | 1 | pfleura2 | ! If (PROG=="VASP") STOP |
220 | 1 | pfleura2 | |
221 | 1 | pfleura2 | |
222 | 1 | pfleura2 | ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid |
223 | 1 | pfleura2 | ! but we have to convert it into Zmat if COORD=Zmat |
224 | 1 | pfleura2 | SELECT CASE (COORD) |
225 | 1 | pfleura2 | CASE ("ZMAT") |
226 | 1 | pfleura2 | ALLOCATE(GradTmp(3*Nat)) |
227 | 1 | pfleura2 | if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_int" |
228 | 1 | pfleura2 | CALL CalcBMat_int (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome) |
229 | 1 | pfleura2 | |
230 | 1 | pfleura2 | if (debug) WRITE(*,*) "DBG EGRAD Calling ConvGrad_Cart2Int" |
231 | 1 | pfleura2 | CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
232 | 1 | pfleura2 | |
233 | 1 | pfleura2 | if (debug) WRITE(*,*) "DBG EGRAD Storing Grad" |
234 | 1 | pfleura2 | Grad(1)=GradTmp(4) |
235 | 1 | pfleura2 | Grad(2)=GradTmp(7) |
236 | 1 | pfleura2 | ! We might have troubles whith angles that are not in the [0:pi] range because, |
237 | 1 | pfleura2 | ! when converted to catesian coord, they do appear in the [0:Pi] range to gaussian... |
238 | 1 | pfleura2 | ! so that the derivative is not good, and a multiplicative factor should be added... |
239 | 1 | pfleura2 | ! |
240 | 1 | pfleura2 | ! This in fact should be taken care of in B mat calculation... |
241 | 1 | pfleura2 | ! |
242 | 1 | pfleura2 | IF ((Geom(3).LE.0).OR.(Geom(3).GE.Pi)) THEN |
243 | 1 | pfleura2 | Grad(3)=-1.0d0*GradTmp(8) |
244 | 1 | pfleura2 | ELSE |
245 | 1 | pfleura2 | Grad(3)=GradTmp(8) |
246 | 1 | pfleura2 | END IF |
247 | 1 | pfleura2 | Idx=4 |
248 | 1 | pfleura2 | DO I=4,Nat |
249 | 1 | pfleura2 | Grad(Idx)=GradTmp(3*i-2) |
250 | 1 | pfleura2 | Grad(Idx+1)=GradTmp(3*i-1) |
251 | 1 | pfleura2 | Grad(Idx+2)=GradTmp(3*i) |
252 | 1 | pfleura2 | Idx=Idx+3 |
253 | 1 | pfleura2 | END DO |
254 | 1 | pfleura2 | DEALLOCATE(GradTmp) |
255 | 1 | pfleura2 | CASE ('BAKER') |
256 | 1 | pfleura2 | ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid |
257 | 1 | pfleura2 | ! but we have to convert it into internal coordinates if COORD=Baker |
258 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!! |
259 | 1 | pfleura2 | ! |
260 | 1 | pfleura2 | ! PFL Debug |
261 | 1 | pfleura2 | ! |
262 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!! |
263 | 1 | pfleura2 | if (debugPFL) THEN |
264 | 1 | pfleura2 | WRITE(*,*) "DBG PFL Egrad_Baker... computing dzdc" |
265 | 1 | pfleura2 | if (.not.ALLOCATED(indzmat)) THEN |
266 | 1 | pfleura2 | ALLOCATE(indzmat(Nat,5)) |
267 | 1 | pfleura2 | IndZmat=0 |
268 | 1 | pfleura2 | Indzmat(1,1)=1 |
269 | 1 | pfleura2 | IndZmat(2,1)=2 |
270 | 1 | pfleura2 | IndZmat(2,2)=1 |
271 | 1 | pfleura2 | IndZmat(3,1)=3 |
272 | 1 | pfleura2 | IndZmat(3,2)=2 |
273 | 1 | pfleura2 | IndZmat(3,3)=1 |
274 | 1 | pfleura2 | IndZmat(4,1)=4 |
275 | 1 | pfleura2 | IndZmat(4,2)=3 |
276 | 1 | pfleura2 | IndZmat(4,3)=2 |
277 | 1 | pfleura2 | IndZmat(4,4)=1 |
278 | 1 | pfleura2 | END IF |
279 | 1 | pfleura2 | IF (.NOT.ALLOCATED(DzDc)) THEN |
280 | 1 | pfleura2 | ALLOCATE(DzDc(3,nat,3,Nat)) |
281 | 1 | pfleura2 | END IF |
282 | 1 | pfleura2 | if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat)) |
283 | 1 | pfleura2 | DO I=1,Nat |
284 | 1 | pfleura2 | GeomTmp(1,I)=GeomCart(OrderInv(I),1) |
285 | 1 | pfleura2 | GeomTmp(2,I)=GeomCart(OrderInv(i),2) |
286 | 1 | pfleura2 | GeomTmp(3,I)=GeomCart(OrderInv(i),3) |
287 | 1 | pfleura2 | END DO |
288 | 1 | pfleura2 | |
289 | 1 | pfleura2 | DzDc=0.d0 |
290 | 1 | pfleura2 | CALL CalcBMat_int (nat, GeomTmp, indzmat, dzdc, massat,atome) |
291 | 1 | pfleura2 | |
292 | 1 | pfleura2 | END IF ! if (debugPFL) |
293 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!!!!!!! |
294 | 1 | pfleura2 | ! Debugging PFL |
295 | 1 | pfleura2 | !!!!!!!!!!!!!!!!!!!!!!!! |
296 | 1 | pfleura2 | |
297 | 1 | pfleura2 | WRITE(*,*) "BTransInv_local Trans that is used originally" |
298 | 1 | pfleura2 | DO J=1,3*Nat |
299 | 1 | pfleura2 | WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J) |
300 | 1 | pfleura2 | END DO |
301 | 1 | pfleura2 | |
302 | 1 | pfleura2 | WRITE(*,*) "Calculating actual values using GeomCart" |
303 | 1 | pfleura2 | if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat)) |
304 | 1 | pfleura2 | GeomTmp(1,:)=GeomCart(1:Nat,1) |
305 | 1 | pfleura2 | GeomTmp(2,:)=GeomCart(1:Nat,2) |
306 | 1 | pfleura2 | GeomTmp(3,:)=GeomCart(1:Nat,3) |
307 | 1 | pfleura2 | |
308 | 1 | pfleura2 | ! Computing B^prim: |
309 | 1 | pfleura2 | FAloBBT=.NOT.ALLOCATED(BBT) |
310 | 1 | pfleura2 | FAloBBTInv=.NOT.ALLOCATED(BBT_inv) |
311 | 1 | pfleura2 | FAloBPrimT=.NOT.ALLOCATED(BprimT) |
312 | 1 | pfleura2 | if (FAloBPrimT) ALLOCATE(Bprimt(3*Nat,NPrim)) |
313 | 1 | pfleura2 | if (FAloBBT) ALLOCATE(BBt(NCoord,NCoord)) |
314 | 1 | pfleura2 | if (FAloBBTInv) ALLOCATE(BBt_inv(NCoord,NCoord)) |
315 | 1 | pfleura2 | BprimT=0.d0 |
316 | 1 | pfleura2 | ScanCoord=>Coordinate |
317 | 1 | pfleura2 | I=0 |
318 | 1 | pfleura2 | DO WHILE (Associated(ScanCoord%next)) |
319 | 1 | pfleura2 | I=I+1 |
320 | 1 | pfleura2 | SELECT CASE (ScanCoord%Type) |
321 | 1 | pfleura2 | CASE ('BOND') |
322 | 1 | pfleura2 | CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2,GeomTmp,BprimT(1,I)) |
323 | 1 | pfleura2 | CASE ('ANGLE') |
324 | 1 | pfleura2 | CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,GeomTmp,BprimT(1,I)) |
325 | 1 | pfleura2 | CASE ('DIHEDRAL') |
326 | 1 | pfleura2 | CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,ScanCoord%At4,GeomTmp,BprimT(1,I)) |
327 | 1 | pfleura2 | END SELECT |
328 | 1 | pfleura2 | ScanCoord => ScanCoord%next |
329 | 1 | pfleura2 | END DO |
330 | 1 | pfleura2 | |
331 | 1 | pfleura2 | if (debug) THEN |
332 | 1 | pfleura2 | WRITE(*,*) "Bprim " |
333 | 1 | pfleura2 | DO J=1,3*Nat |
334 | 1 | pfleura2 | WRITE(*,'(50(1X,F12.6))') BprimT(J,:) |
335 | 1 | pfleura2 | END DO |
336 | 1 | pfleura2 | END IF |
337 | 1 | pfleura2 | |
338 | 1 | pfleura2 | BMat_BakerT = 0.d0 |
339 | 1 | pfleura2 | DO I=1,NCoord |
340 | 1 | pfleura2 | DO J=1,NPrim |
341 | 1 | pfleura2 | !BprimT is transpose of B^prim. |
342 | 1 | pfleura2 | !B = UMat^T B^prim, B^T = (B^prim)^T UMat |
343 | 1 | pfleura2 | BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat_local(J,I) |
344 | 1 | pfleura2 | END DO |
345 | 1 | pfleura2 | END DO |
346 | 1 | pfleura2 | |
347 | 1 | pfleura2 | BBT = 0.d0 |
348 | 1 | pfleura2 | DO I=1,NCoord |
349 | 1 | pfleura2 | DO J=1,3*Nat ! BBT(:,I) forms BB^T |
350 | 1 | pfleura2 | BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I) |
351 | 1 | pfleura2 | END DO |
352 | 1 | pfleura2 | END DO |
353 | 1 | pfleura2 | |
354 | 1 | pfleura2 | BBT_inv = 0.d0 |
355 | 1 | pfleura2 | |
356 | 1 | pfleura2 | Call GenInv(NCoord,BBT,BBT_inv,NCoord) |
357 | 1 | pfleura2 | |
358 | 1 | pfleura2 | ! ALLOCATE(V(NCoord,NCoord)) |
359 | 1 | pfleura2 | ! tol = 1e-10 |
360 | 1 | pfleura2 | ! ! BBT is destroyed by GINVSE |
361 | 1 | pfleura2 | ! Call GINVSE(BBT,NCoord,NCoord,BBT_inv,NCoord,NCoord,NCoord,tol,V,NCoord,FAIL,IOOUT) |
362 | 1 | pfleura2 | ! DEALLOCATE(V) |
363 | 1 | pfleura2 | ! IF(Fail) Then |
364 | 1 | pfleura2 | ! WRITE (*,*) "Failed in generalized inverse, L220, ConvertBaker...f90" |
365 | 1 | pfleura2 | ! STOP |
366 | 1 | pfleura2 | ! END IF |
367 | 1 | pfleura2 | |
368 | 1 | pfleura2 | !Print *, 'BBT_inv=' |
369 | 1 | pfleura2 | DO J=1,NCoord |
370 | 1 | pfleura2 | ! WRITE(*,'(50(1X,F10.2))') BBT_inv(:,J) |
371 | 1 | pfleura2 | ! Print *, BBT_inv(:,J) |
372 | 1 | pfleura2 | END DO |
373 | 1 | pfleura2 | !Print *, 'End of BBT_inv' |
374 | 1 | pfleura2 | |
375 | 1 | pfleura2 | ! Calculation of (B^T)^-1 = (BB^T)^-1B: |
376 | 1 | pfleura2 | BTransInv_local = 0.d0 |
377 | 1 | pfleura2 | DO I=1,3*Nat |
378 | 1 | pfleura2 | DO J=1,NCoord |
379 | 1 | pfleura2 | BTransInv_local(:,I)=BTransInv_local(:,I)+BBT_inv(:,J)*BMat_BakerT(I,J) |
380 | 1 | pfleura2 | END DO |
381 | 1 | pfleura2 | END DO |
382 | 1 | pfleura2 | |
383 | 1 | pfleura2 | Print *, 'BMat_BakerT=' |
384 | 1 | pfleura2 | DO J=1,3*Nat |
385 | 1 | pfleura2 | WRITE(*,'(50(1X,F12.8))') BMat_BakerT(:,J) |
386 | 1 | pfleura2 | END DO |
387 | 1 | pfleura2 | |
388 | 1 | pfleura2 | WRITE(*,*) "BTransInv_local Trans corresponding to GeomCart" |
389 | 1 | pfleura2 | DO J=1,3*Nat |
390 | 1 | pfleura2 | WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J) |
391 | 1 | pfleura2 | END DO |
392 | 1 | pfleura2 | |
393 | 1 | pfleura2 | if (FAloBPrimT) DEALLOCATE(Bprimt) |
394 | 1 | pfleura2 | if (FAloBBT) DEALLOCATE(BBt) |
395 | 1 | pfleura2 | if (FAloBBTInv) DEALLOCATE(BBt_inv) |
396 | 1 | pfleura2 | |
397 | 1 | pfleura2 | Grad=0.d0 |
398 | 1 | pfleura2 | DO I=1, 3*Nat |
399 | 1 | pfleura2 | ! Here Grad is gradient in Baker coordinates. GradCart(3*Nat) |
400 | 1 | pfleura2 | Grad(:) = Grad(:) + BTransInv_local(:,I)*GradCart(I) !BTransInv_local = BTransInv in Opt_Geom.f90 |
401 | 1 | pfleura2 | END DO |
402 | 1 | pfleura2 | !WRITE(*,*) 'In Egrad.f90, L263, Gradient:' |
403 | 1 | pfleura2 | !WRITE(*,'(12(1X,F8.4))') Grad(1:NCoord) |
404 | 1 | pfleura2 | |
405 | 1 | pfleura2 | |
406 | 1 | pfleura2 | CASE ('MIXED') |
407 | 1 | pfleura2 | ALLOCATE(GradTmp(3*Nat)) |
408 | 1 | pfleura2 | if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_mixed" |
409 | 1 | pfleura2 | CALL CalcBMat_mixed (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome) |
410 | 1 | pfleura2 | |
411 | 1 | pfleura2 | if (Debug) THEN |
412 | 1 | pfleura2 | WRITE(*,*) "DzDc" |
413 | 1 | pfleura2 | DO I=1,Nat |
414 | 1 | pfleura2 | DO J=1,3 |
415 | 1 | pfleura2 | WRITE(*,'(50(1X,F12.6))') dzdc(J,I,:,:) |
416 | 1 | pfleura2 | END DO |
417 | 1 | pfleura2 | END DO |
418 | 1 | pfleura2 | END IF |
419 | 1 | pfleura2 | |
420 | 1 | pfleura2 | |
421 | 1 | pfleura2 | CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
422 | 1 | pfleura2 | DO I=1,Nat |
423 | 1 | pfleura2 | WRITE(*,'(1X,3(1X,F10.5))') GradTmp(3*I-2:3*I) |
424 | 1 | pfleura2 | END DO |
425 | 1 | pfleura2 | SELECT CASE (NCART) |
426 | 1 | pfleura2 | CASE (1) |
427 | 1 | pfleura2 | Grad(1:3)=GradTmp(1:3) |
428 | 1 | pfleura2 | Grad(4)=GradTmp(4) |
429 | 1 | pfleura2 | Grad(5)=GradTmp(7) |
430 | 1 | pfleura2 | Grad(6)=GradTmp(8) |
431 | 1 | pfleura2 | Idx=7 |
432 | 1 | pfleura2 | IBeg=4 |
433 | 1 | pfleura2 | CASE(2) |
434 | 1 | pfleura2 | Grad(1:3)=GradTmp(1:3) |
435 | 1 | pfleura2 | Grad(4:6)=GradTmp(4:6) |
436 | 1 | pfleura2 | Grad(7)=GradTmp(7) |
437 | 1 | pfleura2 | Grad(8)=GradTmp(8) |
438 | 1 | pfleura2 | Idx=9 |
439 | 1 | pfleura2 | IBeg=4 |
440 | 1 | pfleura2 | CASE DEFAULT |
441 | 1 | pfleura2 | Idx=1 |
442 | 1 | pfleura2 | IBeg=1 |
443 | 1 | pfleura2 | END SELECT |
444 | 1 | pfleura2 | DO I=IBeg,Nat |
445 | 1 | pfleura2 | Grad(Idx)=GradTmp(3*i-2) |
446 | 1 | pfleura2 | Grad(Idx+1)=GradTmp(3*i-1) |
447 | 1 | pfleura2 | Grad(Idx+2)=GradTmp(3*i) |
448 | 1 | pfleura2 | Idx=Idx+3 |
449 | 1 | pfleura2 | END DO |
450 | 1 | pfleura2 | DEALLOCATE(GradTmp) |
451 | 1 | pfleura2 | CASE ("CART","HYBRID") |
452 | 1 | pfleura2 | Grad=GradCart |
453 | 1 | pfleura2 | CASE DEFAULT |
454 | 1 | pfleura2 | WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in Egradients. STOP" |
455 | 1 | pfleura2 | STOP |
456 | 1 | pfleura2 | END SELECT |
457 | 1 | pfleura2 | |
458 | 1 | pfleura2 | DEALLOCATE(GradCart) |
459 | 1 | pfleura2 | DEALLOCATE(x,y,z) |
460 | 1 | pfleura2 | |
461 | 1 | pfleura2 | IF (Debug) WRITE(*,*) 'DBG EGRAD grad',grad(1:NCoord) |
462 | 1 | pfleura2 | if (debug) Call Header("Egrad Over") |
463 | 1 | pfleura2 | |
464 | 1 | pfleura2 | !999 CONTINUE |
465 | 1 | pfleura2 | !if (.NOT.Ftmp) WRITE(*,*) 'We should not be here !!!!' |
466 | 1 | pfleura2 | !STOP |
467 | 1 | pfleura2 | ! ====================================================================== |
468 | 1 | pfleura2 | end subroutine Egrad |