-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathsymmetry.f90
330 lines (255 loc) · 8.47 KB
/
symmetry.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
!
module symmetry
use accuracy
implicit none
public SymmetryInitialize,sym,correlate_to_Cs
type ScIIT
integer(ik) :: Noper ! Number of operations in the CII operator
integer(ik) :: Nzeta ! Number of symmetric elements taking into account the degeneracies
real(ark),pointer :: ioper(:) ! the operation number in the MS group
integer(ik),pointer :: coeff(:) ! coefficients of the CII operator
integer(ik),pointer :: izeta(:) ! symmetry indentification as a eigenvalues of the CII operator
end type ScIIT
type SymmetryT
character(len=cl) :: group = 'C' ! The symmetry group
integer(ik) :: NrepresCs = 2 ! Number of irreduc. represent. for Cs(M)
integer(ik) :: Nrepresen = 1 ! Number of irreduc. represent.
integer(ik) :: Noper = 1 ! Number of operations
integer(ik) :: Nclasses = 1 ! Number of classes
integer(ik),pointer :: Nelements(:) ! Number of elements in a class
integer(ik),pointer :: characters(:,:)! Character table
type(SrepresT),pointer :: irr(:,:) ! irreducible representaion
integer(ik),pointer :: degen(:) ! degeneracy
character(len=3),pointer :: label(:) ! The symmetry label
integer(ik) :: Maxdegen = 1 ! Maximal degeneracy order
integer(ik),pointer :: igenerator(:) ! address of the class generator in the sym%Ngroup list
type(ScIIT) :: CII ! the elements of the CII operator
real(ark),pointer :: euler(:,:) ! rotational angles equivalent to the group operations
end type SymmetryT
type SrepresT
real(ark),pointer :: repres(:,:) ! matrix representation of the group
end type SrepresT
type(SymmetryT) , save :: sym
contains
subroutine SymmetryInitialize(sym_group)
character(len=cl),intent(in) :: sym_group
integer(ik):: alloc,iclass,gamma,ioper,ielem
real(ark) :: o,p2,p3
!
sym%group=sym_group
!
select case(trim(sym_group))
case("C(M)","C")
sym%Nrepresen=1
sym%Noper=1
sym%Nclasses=1
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters(1,1)=1
sym%degen=(/1/)
sym%Nelements=(/1/)
sym%label=(/'A'/)
do gamma = 1,sym%Nrepresen
ioper = 0
do iclass = 1,sym%Nclasses
do ielem = 1,sym%Nelements(iclass)
!
ioper = ioper + 1
!
allocate(sym%irr(gamma,ioper)%repres(sym%degen(gamma),sym%degen(gamma)),stat=alloc)
!
if (sym%degen(gamma)==1) then
sym%irr(gamma,ioper)%repres(1,1)= sym%characters(gamma,iclass)
endif
!
enddo
enddo
enddo
case("CS(M)","CS")
sym%Nrepresen=2
sym%Noper=2
sym%Nclasses=2
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters= reshape( &
(/ 1, 1, &
1,-1 /),(/2,2/))
sym%degen=(/1,1/)
sym%Nelements=(/1,1/)
sym%label=(/'A''','A"'/)
call irr_allocation
case("C2V(M)","C2V")
sym%Nrepresen=4
sym%Noper=4
sym%Nclasses=4
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters= reshape( &
(/ 1, 1, 1, 1, & ! A1
1, 1,-1,-1, & ! A2
1,-1,-1, 1, & ! B1
1,-1, 1,-1 /),(/4,4/)) ! B2
sym%degen=(/1,1,1,1/)
sym%Nelements=(/1,1,1,1/)
sym%label=(/'A1','A2','B1','B2'/)
!
o = 0.0_ark
p2 = 0.5_ark*pi
p3 = 1.5_ark*pi
!
sym%euler( 1,:) = 0
sym%euler( 2,:) = (/pi,o,o /)
sym%euler( 3,:) = (/o,pi,o/)
sym%euler( 4,:) = (/p2,pi,p3/)
!
call irr_allocation
case("C2H(M)","C2H")
sym%Nrepresen=4
sym%Noper=4
sym%Nclasses=4
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters= reshape( &
(/ 1, 1, 1, 1, & ! Ag
1, 1,-1,-1, & ! Au
1,-1, 1,-1, & ! Bg
1,-1,-1, 1 /),(/4,4/)) ! Bu
sym%degen=(/1,1,1,1/)
sym%Nelements=(/1,1,1,1/)
sym%label=(/'Ag','Au','Bg','Bu'/)
!
call irr_allocation
case("G4(M)","G4")
sym%Nrepresen=4
sym%Noper=4
sym%Nclasses=4
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters= reshape( & ! E (12)(34) E* (12)(34)*
(/ 1, 1, 1, 1, & ! A+
1, 1,-1,-1, & ! A-
1,-1,-1, 1, & ! B+
1,-1, 1,-1 /),(/4,4/)) ! B-
sym%degen=(/1,1,1,1/)
sym%Nelements=(/1,1,1,1/)
sym%label=(/'A+','A-','B+','B-'/)
!
call irr_allocation
case("G4(EM)")
sym%Nrepresen=8
sym%Noper=8
sym%Nclasses=8
sym%CII%Noper = 0
call simple_arrays_allocation
sym%characters= reshape( & ! E a b ab E' E'a E'b E'ab
(/ 1, 1, 1, 1, 1, 1, 1, 1, & ! Ags
1, 1, -1, -1, 1, 1, -1, -1, & ! Aus
1, -1, -1, 1, 1, -1, -1, 1, & ! Bgs
1, -1, 1, -1, 1, -1, 1, -1, & ! Bus
1, 1, -1, -1, -1, -1, 1, 1, & ! Agd
1, 1, 1, 1, -1, -1, -1, -1, & ! Aud
1, -1, 1, -1, -1, 1, -1, 1, & ! Bgd
1, -1, -1, 1, -1, 1, 1, -1 /),(/8 ,8/)) ! Bud
sym%degen=(/1,1,1,1,1,1,1,1/)
sym%Nelements=(/1,1,1,1,1,1,1,1/)
sym%label=(/'Ags','Aus','Bgs','Bus','Agd','Aud','Bgd','Bud'/)
!
call irr_allocation
case default
write(out,"('symmetry: undefined symmetry group ',a)") trim(sym_group)
stop 'symmetry: undefined symmetry group '
end select
!
if (20<sym%Nrepresen) then
!
write(out,"('symmetry: number of elements in _select_gamma_ is too small: ',i8)") 20
stop 'symmetry: size of _select_gamma_ is too small'
!
endif
!
sym%maxdegen = maxval(sym%degen(:),dim=1)
!
! store the address of the group generator from ioper = 1..Noper list
!
ioper = 1
!
do iclass = 1,sym%Nclasses
!
sym%igenerator(iclass) = ioper
ioper = ioper + sym%Nelements(iclass)
!
enddo
contains
subroutine simple_arrays_allocation
integer(ik) :: alloc,nCII
nCII = max(1,sym%CII%Noper)
!
allocate (sym%characters(sym%Nclasses,sym%Nrepresen),sym%irr(sym%Nrepresen,sym%Noper),&
sym%degen(sym%Nrepresen),sym%Nelements(sym%Nclasses),sym%label(sym%Nrepresen),&
sym%igenerator(sym%Nclasses),&
sym%CII%ioper(nCII),sym%CII%coeff(nCII),sym%euler(sym%Noper,3),stat=alloc)
if (alloc/=0) stop 'simple_arrays_allocation - out of memory'
!
sym%CII%coeff = 0
sym%CII%ioper = 1
sym%euler = 0
!
end subroutine simple_arrays_allocation
subroutine irr_allocation
integer(ik) :: gamma,ioper,iclass,ielem,alloc
do gamma = 1,sym%Nrepresen
ioper = 0
do iclass = 1,sym%Nclasses
do ielem = 1,sym%Nelements(iclass)
!
ioper = ioper + 1
!
allocate(sym%irr(gamma,ioper)%repres(sym%degen(gamma),sym%degen(gamma)),stat=alloc)
!
if (sym%degen(gamma)==1) then
sym%irr(gamma,ioper)%repres(1,1)= sym%characters(gamma,iclass)
endif
!
enddo
enddo
enddo
if (alloc/=0) then
write (out,"(' symmetryInitialize ',i9,' error trying to allocate symmetry')") alloc
stop 'symmetryInitialize, symmetries - out of memory'
end if
end subroutine irr_allocation
end subroutine symmetryInitialize
function correlate_to_Cs(iparity,gu) result(isym)
!
implicit none
!
integer(ik),intent(in) :: iparity,gu
integer(ik) :: isym
!
if (sym%Nrepresen==sym%NrepresCs) then
!
isym = iparity
return
!
endif
!
if (iparity==1.and.gu==1) then
! A1
isym = 1
!
elseif (iparity==2.and.gu==1) then
! B1
isym = 3
!
elseif (iparity==1.and.gu==-1) then
! B2
isym = 4
!
else
! A2
isym = 2
!
endif
!
end function correlate_to_Cs
end module symmetry