Statistiques
| Révision :

root / src / Calc_Xprim.f90 @ 4

Historique | Voir | Annoter | Télécharger (6,81 ko)

1
SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef)
2
!     
3
! This subroutine uses the description of a list of Coordinates
4
! to compute the values of the coordinates for a given geometry.
5
!
6
!!!!!!!!!!
7
! Input:
8
!   Na: INTEGER, Number of atoms
9
!  x,y,z(Na): REAL, cartesian coordinates of the considered geometry
10
! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes
11
! NPrim, INTEGER: Number of coordinates to compute
12
!
13
! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for
14
! a former geometry. Useful for Dihedral angles evolution...
15

    
16
!!!!!!!!!!!
17
! Output:
18
! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates
19
!
20
!!!!!!!!!
21

    
22
  Use VarTypes
23
  Use Io_module
24
  Use Path_module, only : pi
25

    
26
  IMPLICIT NONE
27

    
28
  Type (ListCoord), POINTER :: Coordinate
29
  INTEGER(KINT), INTENT(IN) :: Nat,NPrim
30
  REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat)
31
  REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim) 
32
  REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim)
33

    
34

    
35
  Type (ListCoord), POINTER :: ScanCoord
36

    
37
  real(KREAL) :: vx,vy,vz,dist, Norm
38
  real(KREAL) :: vx1,vy1,vz1,norm1
39
  real(KREAL) :: vx2,vy2,vz2,norm2
40
  real(KREAL) :: vx3,vy3,vz3,norm3
41
  real(KREAL) :: vx4,vy4,vz4,norm4
42
  real(KREAL) :: vx5,vy5,vz5,norm5
43
  real(KREAL) :: val,val_d, Q, T
44

    
45
  INTEGER(KINT) :: I,J, n1,n2,n3,n4
46

    
47
  REAL(KREAL) :: sAngleIatIKat, sAngleIIatLat
48
  REAL(KREAL) :: DiheTmp
49

    
50
  LOGICAL :: debug, debugPFL
51

    
52
  INTERFACE
53
     function valid(string) result (isValid)
54
       CHARACTER(*), intent(in) :: string
55
       logical                  :: isValid
56
     END function VALID
57

    
58
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
59
        use Path_module, only :  Pi,KINT, KREAL
60
       real(KREAL) ::  v1x,v1y,v1z,norm1
61
       real(KREAL) ::  v2x,v2y,v2z,norm2
62
       real(KREAL) ::  angle
63
     END FUNCTION ANGLE
64

    
65
     FUNCTION SinAngle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
66
        use Path_module, only :  Pi,KINT, KREAL
67
       real(KREAL) ::  v1x,v1y,v1z,norm1
68
       real(KREAL) ::  v2x,v2y,v2z,norm2
69
       real(KREAL) ::  SinAngle
70
     END FUNCTION SINANGLE
71

    
72

    
73
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
74
        use Path_module, only :  Pi,KINT, KREAL
75
       real(KREAL) ::  v1x,v1y,v1z,norm1
76
       real(KREAL) ::  v2x,v2y,v2z,norm2
77
       real(KREAL) ::  v3x,v3y,v3z,norm3
78
       real(KREAL) ::  angle_d,ca,sa
79
     END FUNCTION ANGLE_D
80

    
81
  END INTERFACE
82

    
83

    
84
  debug=valid("Calc_Xprim")
85
  debugPFL=valid("BakerPFL")
86
  if (debug) WRITE(*,*) "============= Entering Cal_XPrim =============="
87

    
88

    
89
  IF (debug) THEN
90
     WRITE(*,*) "DBG Calc_Xprim, geom"
91
     DO I=1,Nat
92
        WRITE(*,'(1X,I5,3(1X,F15.3))') I,X(I),y(i),z(i)
93
     END DO
94
     WRITE(*,*) "XPrimRef"
95
     WRITE(*,'(15(1X,F10.6))') XPrimRef
96
  END IF
97

    
98

    
99
!  WRITE(*,*) "Coordinate:",associated(Coordinate)
100

    
101
     ScanCoord=>Coordinate
102

    
103
!  WRITE(*,*) "ScanCoord:",associated(ScanCoord),ScanCoord%Type
104

    
105
!     WRITE(*,*) "coucou"
106
     I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
107
     DO WHILE (Associated(ScanCoord%next))
108
        I=I+1
109
!        WRITE(*,*) i
110
        SELECT CASE (ScanCoord%Type)
111
        CASE ('BOND')
112
           Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
113
           Xprimitive(I) = Norm2  
114
        CASE ('ANGLE')
115
           Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx1,vy1,vz1,Norm1)
116
           Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
117
           Xprimitive(I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
118
        CASE ('DIHEDRAL')
119
           Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx1,vy1,vz1,Norm1)
120
           Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx2,vy2,vz2,Norm2)
121
           Call vecteur(ScanCoord%At3,ScanCoord%At4,x,y,z,vx3,vy3,vz3,Norm3)
122
           Call produit_vect(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2, &
123
                vx4,vy4,vz4,norm4)
124
           Call produit_vect(vx3,vy3,vz3,norm3,vx2,vy2,vz2,norm2, &
125
                vx5,vy5,vz5,norm5)
126

    
127
                 DiheTmp= angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
128
                         vx2,vy2,vz2,norm2)
129
                 Xprimitive(I) = DiheTmp*Pi/180.
130
! PFL 15th March 2008 ->
131
! I think that the test on changes less than Pi should be enough
132
!! We treat large dihedral angles differently as +180=-180 mathematically and physically
133
!! but this causes lots of troubles when converting baker to cart.
134
!! So we ensure that large dihedral angles always have the same sign
135
!                    if (abs(ScanCoord%SignDihedral).NE.1) THEN
136
!                        ScanCoord%SignDihedral=Int(Sign(1.D0,DiheTmp))
137
!                    ELSE
138
!                        If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN
139
!                          Xprimitive(I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi
140
!                       END IF
141
!                  END IF
142
!!!! <- PFL 15th March 2008
143
! Another test... will all this be consistent ??? 
144
! We want the shortest path, so we check that the change in dihedral angles is less than Pi:
145
                  IF (Present(XPrimRef)) THEN
146
                     IF (abs(Xprimitive(I)-XPrimRef(I)).GE.Pi) THEN
147
                       if (debug) THEN 
148
                         WRITE(*,*) "Pb dihedral, i,Xprimivite,XPrimref=",i,XPrimitive(I),XPrimRef(I)
149
                         WRITE(*,*) "In deg Xprimivite,XPrimref=",XPrimitive(I)*180./Pi,XPrimRef(I)*180/Pi
150
                       END IF
151
                        if ((Xprimitive(I)-XPrimRef(I)).GE.Pi) THEN
152
                           Xprimitive(I)=Xprimitive(I)-2.d0*Pi
153
                        ELSE
154
                           Xprimitive(I)=Xprimitive(I)+2.d0*Pi
155
                        END IF
156
                     END IF
157
                       if (debug) WRITE(*,*) " New Xprimivite",XPrimitive(I),XPrimitive(I)*180./Pi
158
                  END IF
159
        END SELECT
160
        ScanCoord => ScanCoord%next
161
     END DO ! matches DO WHILE (Associated(ScanCoord%next))
162

    
163

    
164

    
165
  IF (debug) THEN
166
     WRITE(*,*) "DBG Calc_Xprim Values"
167
     
168
     ScanCoord=>Coordinate
169
     I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
170
     DO WHILE (Associated(ScanCoord%next))
171
        I=I+1
172
        SELECT CASE (ScanCoord%Type)
173
        CASE ('BOND')
174
           WRITE(*,'(1X,I3,":",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,Xprimitive(I)
175
        CASE ('ANGLE')
176
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
177
            ScanCoord%At2, ScanCoord%At3,Xprimitive(I)*180./Pi
178
        CASE ('DIHEDRAL')
179
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
180
           ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,Xprimitive(I)*180./Pi
181
        END SELECT
182
        ScanCoord => ScanCoord%next
183
     END DO ! matches DO WHILE (Associated(ScanCoord%next))
184
  END IF
185
  if (debug) WRITE(*,*) "============= Cal_XPrim OVER =============="
186
END SUBROUTINE Calc_Xprim