Line data Source code
1 : !!****m* ABINIT/m_esymm
2 : !! NAME
3 : !! m_esymm
4 : !!
5 : !! FUNCTION
6 : !! Objects and procedures to find the irreducible representations associated to electronic eigenstates.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_esymm
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_errors
27 :
28 : use m_io_tools, only : file_exists
29 : use m_matrix, only : matr3inv
30 : use m_symtk, only : sg_multable, symrelrot, littlegroup_q
31 : use m_symfind, only : symbrav
32 : use m_fstrings, only : int2char10, itoa, sjoin
33 : use m_numeric_tools, only : print_arr, set2unit, get_trace
34 : use m_hide_lapack, only : xgeev, xginv
35 : use m_crystal, only : crystal_t
36 : use m_defs_ptgroups, only : point_group_t, irrep_t, irrep_free, copy_irrep
37 : use m_ptgroups, only : get_classes, point_group_init, mult_table, sum_irreps
38 :
39 : implicit none
40 :
41 : private
42 : !!***
43 :
44 : ! Error codes.
45 : integer,private,parameter :: ESYM_NOERROR = 0
46 : integer,private,parameter :: ESYM_ACCDEG_ERROR = 10
47 : integer,private,parameter :: ESYM_CLASSIFICATION_ERROR= 11
48 : integer,private,parameter :: ESYM_ORTHO_ERROR = 12
49 : integer,private,parameter :: ESYM_UNITARY_ERROR = 13
50 : integer,private,parameter :: ESYM_PTG_WRONG_MAPPING = 20
51 : integer,private,parameter :: ESYM_HERRING_WRONG_TEST = 30
52 : integer,private,parameter :: ESYM_HEUR_WRONG_NCLASSES = 40
53 : integer,private,parameter :: ESYM_HEUR_WRONG_DIMS = 41
54 :
55 : !----------------------------------------------------------------------
56 :
57 : !!****t* m_esymm/esymm_t
58 : !! NAME
59 : !! esymm_t
60 : !!
61 : !! FUNCTION
62 : !! Dataype gathering data and tables needed to analize the symmetries
63 : !! of electronic states at a given k-point via Group Theory.
64 : !!
65 : !! SOURCE
66 :
67 : type,public :: esymm_t
68 :
69 : integer :: nspinor
70 : ! Number of spinor components.
71 :
72 : integer :: first_ib
73 : ! Index of the first treated band.
74 :
75 : integer :: nbnds
76 : ! Number of bands for this k-point and spin.
77 :
78 : integer :: nclass
79 : ! The number of classes in the group of k.
80 :
81 : integer :: nsym_gk
82 : ! Number of symmetries in the group of k. Namely that the set of symmetries such that Sk = k +G0.
83 :
84 : integer :: nsym_trgk
85 : ! Number of symmetries in the extended group of k. Namely that the set of symmetries such that -Sk = k + G0.
86 :
87 : integer :: err_status = ESYM_NOERROR
88 : ! Flag signaling if the classification algorithm succeed or not.
89 :
90 : real(dp) :: tol_deg
91 : ! Energy tolerance below which two states are considered degenerate.
92 :
93 : logical :: can_use_tr
94 : ! .TRUE. if time-reversal can be used
95 :
96 : logical :: only_trace
97 : ! if .TRUE. only the trace of a single matrix per class is calculated
98 : ! this is the standard way used to analyze bands symmetries. If .FALSE.
99 : ! the full matrices of the irreducible representations are calculated and stored
100 :
101 : logical :: has_spatial_inv
102 : ! .TRUE. if the inversion belongs to the space group
103 :
104 : logical :: nonsymmorphic_at_zoneborder
105 : ! if .TRUE. analysis cannot be performed since kpt is
106 : ! at border zone and non-zero fractional translations are present in the space group
107 :
108 : logical :: has_chtabs
109 : ! True if Ref_irreps and character tables are available (tables are initialized either
110 : ! from point group irreps or from an external database downloaded from the Bilbao server)
111 :
112 : real(dp) :: kpt(3)
113 : ! The crystalline momentum of the wavefunctions in reduced coordinates.
114 :
115 : character(len=500) :: err_msg = "None"
116 : ! Error message:
117 :
118 : integer,allocatable :: g0(:,:)
119 : ! (3,nsym_gk)
120 : ! The umklapp g0 vector associated to each little group operation.
121 :
122 : integer,allocatable :: tr_g0(:,:)
123 : ! (3,nsym_trgk)
124 : ! The umklapp g0 vector associated to each little group operation.
125 :
126 : integer :: ndegs
127 : ! Number of degenerate states.
128 :
129 : integer,allocatable :: nelements(:)
130 : ! (nclass)
131 : ! Number of symmetry operations in each class.
132 :
133 : integer,allocatable :: sgk2symrec(:)
134 : ! (nsym_gk)
135 : ! Mapping between the symmetries of the group of k and the symrec(l) array.
136 : ! The symmetries of the little group are always packed in classes to facilitate
137 : ! the calculation of the character of the irrep. Abinit symmetries are randomly ordered.
138 :
139 : integer,allocatable :: tr_sgk2symrec(:)
140 : ! (nsym_trgk)
141 : ! Mapping between the symmetries of the group of k and the symrec(l) array.
142 : ! The symmetries of the little group are always packed in classes to facilitate
143 : ! the calculation of the character of the irrep. Abinit symmetries are randomly ordered.
144 :
145 : integer,allocatable :: herring_test(:)
146 : ! (nclass)
147 : ! The result of Herring test for each irreducible representantion of the group of k.
148 : ! Possible values are: +1, 0, -1
149 :
150 : integer,allocatable :: b2irrep(:)
151 : ! (nbnds)
152 : ! For each band, the index of the irreducible representation in Ref_irreps.
153 :
154 : type(coeffi1_type),allocatable :: irrep2b(:)
155 : ! irrep2b(0:nclass)%value(:)
156 : ! Ragged arrays with the mapping between the set of irreducible representation and the band indices.
157 : ! irrep2b(irp)%value(:) gives the indices of the states belonging to irrep irp, irp=1,nclass
158 : ! irrep2b(0)%value(:) stores the indices of the states that have not been classified due to
159 : ! the presence of an accidental degeneracy.
160 :
161 : integer,allocatable :: degs_bounds(:,:)
162 : ! degs_bounds(2,ndegs)
163 : ! degs_bounds(1,idg)= first band index of the degenerate set idg=1,ndegs
164 : ! degs_bounds(2,idg)= final band index of the degenerate set idg=1,ndegs
165 :
166 : integer,allocatable :: degs_dim(:)
167 : ! (ndegs)
168 : ! Number of states in each degenerate subspace. Cannot be larger that nclass provided
169 : ! that no accidental degeneracy occurs.
170 :
171 : !% integer,allocatable :: class_ids(:,:)
172 : ! class_ids(2,nclass)
173 : ! (1,icl) = index of the first symmetry of class icl
174 : ! (2,icl) = index of the last symmetry of class icl
175 : ! Note that symmetries in sym are packed in classes.
176 :
177 : type(irrep_t),allocatable :: Calc_irreps(:)
178 : ! (ndegs)
179 : ! The representations of the little group of k calculated from the wavefunctions. <\phi_nk|R_t|\phi_mk>
180 : ! where R_t belong to the little group of k.
181 : ! They represent an unitary irreducible representation provided that no accidental degeneracy occurs.
182 :
183 : type(irrep_t),allocatable :: trCalc_irreps(:)
184 : ! (ndegs)
185 : ! The representations of the little group of k calculated from the wavefunctions. <\phi_nk|R_t|\phi_mk>
186 : ! where R_t belong to the little group of k.
187 : ! They represent an unitary irreducible representation provided that no accidental degeneracy occurs.
188 :
189 : type(irrep_t),allocatable :: Ref_irreps(:)
190 : ! (nclass)
191 : ! Reference irreducible representations of the group of k derived from the point group
192 : ! or from the external database downloaded from the Bilbao web site.
193 :
194 : contains
195 : procedure :: init => esymm_init ! Initialize the object
196 : procedure :: print => esymm_print ! Print info
197 : procedure :: finalize => esymm_finalize ! Finalize the object
198 : procedure :: failed => esymm_failed ! True if symmetry analysis failed.
199 : procedure :: symmetrize_mels => esymm_symmetrize_mels ! Symmetrize given matrix elements
200 : procedure :: free => esymm_free_0D ! Free memory
201 : !procedure :: which_irrep => which_irrep
202 : end type esymm_t
203 :
204 : public :: esymm_free ! Free memory
205 : !!***
206 :
207 : !----------------------------------------------------------------------
208 :
209 : !public :: polish_irreps ! TODO method of Irreps_t, therefore should be moved to m_ptgroups.
210 : ! but first one has to solve the dependency on m_abilasi and scalapack
211 : interface esymm_free
212 : module procedure esymm_free_0D
213 : module procedure esymm_free_2D
214 : end interface esymm_free
215 :
216 : contains
217 : !!***
218 :
219 : !----------------------------------------------------------------------
220 :
221 : !!****f* m_esymm/esymm_init
222 : !! NAME
223 : !! esymm_init
224 : !!
225 : !! FUNCTION
226 : !! Initialize a esymm_t datatype containing data and parameters
227 : !! needed to analyze the irreducible representations at a particular k-point.
228 : !!
229 : !! INPUTS
230 : !! kpt_in(3)=The k-point where the classification of bands is required.
231 : !! Cryst<crystal_t>=Datatype describing the unit cell and its symmetries.
232 : !! nspinor=number of spinorial components
233 : !! nsppol=number of independent polarizations
234 : !! first_ib=Index of the first band.
235 : !! nbnds=Number of bands for this k-point.
236 : !! ene_k(nbnds)=energies for this k-point. ene_k(1) corresponds to band first_ib.
237 : !! EDIFF_TOL=tolerance below which two states are considered to belong to the same irreducible representation
238 : !!
239 : !! NOTES
240 : !! The present implementation does NOT work at zone border if the little group of
241 : !! kpt_in is non-symmorphic namely there is at least a symmetry operation with non-zero tnons.
242 : !!
243 : !! SOURCE
244 :
245 0 : subroutine esymm_init(esymm, kpt_in, Cryst, only_trace, nspinor, first_ib, nbnds, EDIFF_TOL, ene_k, tolsym)
246 :
247 : !Arguments ------------------------------------
248 : !scalars
249 : class(esymm_t),intent(out) :: esymm
250 : integer,intent(in) :: nbnds,nspinor,first_ib
251 : real(dp),intent(in) :: EDIFF_TOL,tolsym
252 : logical,intent(in) :: only_trace
253 : type(crystal_t),intent(in) :: Cryst
254 : !arrays
255 : real(dp),intent(in) :: ene_k(nbnds),kpt_in(3)
256 :
257 : !Local variables-------------------------------
258 : !scalars
259 : integer :: dim_degs,iband,idg,irp,nacc_deg,isym_gk,grp_ierr
260 : integer :: nsym_fm,idx_fm,idx_gk,idx_trgk,isym,jsym,dummy_timrev !,iholohedry
261 : integer :: iel,icls,msym,iord !isym1,!iprod,dim_irrep,icls2, isym2,isym_tr,
262 : integer :: spgroup,chkprim !,ptgroupma
263 : real(dp) :: mkt
264 : !complex(dp) :: phase_k
265 : character(len=5) :: ptgroup,ptgroup_name
266 : character(len=10) :: spgroup_str
267 : character(len=1000) :: msg
268 : character(len=fnlen) :: lgroup_fname
269 : !arrays
270 : integer :: inversion(3,3), bravais(11),sym_axis(3)
271 0 : integer,allocatable :: degs_bounds(:,:),dim_irreps(:)
272 : real(dp) :: pmat1(3,3),pmat2(3,3),pmat3(3,3),pmat4(3,3),pmat5(3,3),pmat6(3,3)
273 : !real(dp) :: genafm(3)
274 : !integer :: rot2(3,3)
275 0 : integer,allocatable :: elements_idx(:,:),tmp_nelements(:), found(:),symrec_fm(:,:,:),fm2symrec(:)
276 0 : integer,allocatable :: ksym_table(:,:,:),sgk(:,:,:),tr_sgk(:,:,:),dum_symafm(:)
277 0 : integer,allocatable :: new_idx(:),new_g0(:,:),tmp_symrec(:,:,:),conv_symrec(:,:,:) !,tr_conv_symrec(:,:,:)
278 0 : integer,allocatable :: dummy_symafm(:) !, mtab(:,:)
279 : real(dp) :: conv_gprimd(3,3),axes(3,3) !,tau2(3)
280 : !complex(dp),allocatable :: her_test(:) !,mat_test(:,:)
281 0 : complex(dp),allocatable :: phase_mkt(:)
282 0 : type(point_group_t) :: Ptg
283 : ! *************************************************************************
284 :
285 0 : esymm%err_status= ESYM_NOERROR
286 : inversion=RESHAPE((/-1,0,0,0,-1,0,0,0,-1/),(/3,3/))
287 :
288 : ! Initialize basic variables
289 0 : esymm%nspinor = nspinor
290 0 : esymm%first_ib = first_ib
291 0 : esymm%nbnds = nbnds
292 0 : esymm%only_trace = only_trace
293 0 : esymm%tol_deg = EDIFF_TOL
294 0 : esymm%has_spatial_inv= (cryst%idx_spatial_inversion() /= 0)
295 0 : esymm%can_use_tr = .TRUE. !TODO this should be input
296 0 : esymm%has_chtabs = .FALSE.
297 0 : esymm%kpt = kpt_in(:)
298 0 : esymm%nonsymmorphic_at_zoneborder=.FALSE.
299 :
300 : ! Locate degenerate_bands ===
301 0 : esymm%ndegs=1
302 0 : ABI_MALLOC(degs_bounds,(2,nbnds))
303 0 : degs_bounds=0; degs_bounds(1,1)=1
304 :
305 0 : do iband=2,nbnds
306 0 : if (ABS(ene_k(iband)-ene_k(iband-1))>EDIFF_TOL) then
307 0 : degs_bounds(2,esymm%ndegs) = iband-1 + (first_ib-1)
308 0 : esymm%ndegs=esymm%ndegs+1
309 0 : degs_bounds(1,esymm%ndegs) = iband + (first_ib-1)
310 : end if
311 : end do
312 0 : degs_bounds(2,esymm%ndegs)=nbnds + (first_ib-1)
313 :
314 0 : ABI_MALLOC(esymm%degs_bounds,(2,esymm%ndegs))
315 0 : esymm%degs_bounds = degs_bounds(:,1:esymm%ndegs)
316 0 : ABI_FREE(degs_bounds)
317 :
318 : ! Each band is initialized as "Unknown".
319 0 : ABI_MALLOC(esymm%b2irrep,(esymm%nbnds))
320 0 : esymm%b2irrep = 0
321 :
322 : ! Find the group of kpt_in.
323 : ! The small point group is the subset of symrec such that $ S q = q + g0 $
324 : ! Symmetries are packed in classes.
325 : ! For the time being, AFM symmetries are not treated.
326 :
327 0 : write(msg,'(a,3(1x,f7.4))')" Finding the little group of k-point: ",esymm%kpt
328 0 : call wrtout(std_out,msg)
329 :
330 : ! Only FM symmetries are used.
331 0 : nsym_fm = COUNT(Cryst%symafm==1)
332 :
333 0 : if (nsym_fm /= Cryst%nsym) then
334 0 : write(msg,'(4a)')ch10,&
335 0 : "Band classification in terms of magnetic space groups not coded! ",ch10,&
336 0 : "Only the ferromagnetic subgroup will be used "
337 0 : ABI_COMMENT(msg)
338 : end if
339 :
340 0 : ABI_MALLOC(symrec_fm, (3,3,nsym_fm))
341 0 : ABI_MALLOC(fm2symrec, (nsym_fm))
342 :
343 0 : idx_fm = 0
344 0 : do isym=1,Cryst%nsym
345 0 : if (Cryst%symafm(isym) == 1) then
346 0 : idx_fm = idx_fm + 1
347 0 : symrec_fm(:,:,idx_fm) = Cryst%symrec(:,:,isym)
348 0 : fm2symrec(idx_fm) = isym
349 : end if
350 : end do
351 :
352 : ! Find symmetries that preserve k.
353 0 : ABI_MALLOC(ksym_table,(4,2,nsym_fm))
354 0 : ABI_MALLOC(dummy_symafm,(nsym_fm))
355 :
356 0 : dummy_symafm = 1
357 0 : call littlegroup_q(nsym_fm, esymm%kpt, ksym_table, symrec_fm, dummy_symafm, dummy_timrev, prtvol=0)
358 :
359 0 : esymm%nsym_gk =COUNT(ksym_table(4,1,:)==1) ! # S such that S k = k +G0
360 :
361 0 : esymm%nsym_trgk=0
362 0 : if (esymm%can_use_tr) esymm%nsym_trgk=COUNT(ksym_table(4,2,:)==1) ! # S such that -S k = k +G0
363 :
364 : ! Allocate workspace arrays.
365 0 : ABI_MALLOC(sgk,(3,3,esymm%nsym_gk))
366 0 : ABI_MALLOC(tr_sgk,(3,3,esymm%nsym_trgk))
367 :
368 : ! Allocate mapping little-group --> symrec and table for umklapps.
369 0 : ABI_MALLOC(esymm%sgk2symrec,(esymm%nsym_gk))
370 0 : ABI_MALLOC(esymm%g0,(3,esymm%nsym_gk))
371 0 : ABI_MALLOC(esymm%tr_sgk2symrec,(esymm%nsym_trgk))
372 0 : ABI_MALLOC(esymm%tr_g0,(3,esymm%nsym_trgk))
373 :
374 : ! Important NOTE:
375 : ! If nonsymmorphic_at_zoneborder symmetry analysis cannot be performed unless
376 : ! an external database retrieved from the bilbao server (REPRES) is found.
377 0 : idx_gk=0; idx_trgk=0
378 0 : esymm%sgk2symrec=-999; esymm%tr_sgk2symrec=-999
379 :
380 0 : do isym=1,nsym_fm
381 0 : if (ksym_table(4,1,isym)==1) then ! S k = k +G0
382 0 : idx_gk=idx_gk+1
383 0 : sgk(:,:,idx_gk)=symrec_fm(:,:,isym)
384 0 : esymm%g0(:,idx_gk)=ksym_table(1:3,1,isym)
385 0 : esymm%sgk2symrec(idx_gk)=fm2symrec(isym)
386 0 : if (ANY(ksym_table(1:3,1,isym)/=0).and.(ANY(ABS(Cryst%tnons(:,fm2symrec(isym)))>tol6))) then
387 0 : esymm%nonsymmorphic_at_zoneborder=.TRUE.
388 : end if
389 : end if
390 :
391 0 : if (esymm%can_use_tr.and.ksym_table(4,2,isym)==1) then ! -S k = k +G0
392 0 : idx_trgk=idx_trgk+1
393 0 : tr_sgk(:,:,idx_trgk)=symrec_fm(:,:,isym)
394 0 : esymm%tr_g0(:,idx_trgk)=ksym_table(1:3,2,isym)
395 0 : esymm%tr_sgk2symrec(idx_trgk)=fm2symrec(isym)
396 : end if
397 : end do
398 :
399 0 : ABI_FREE(ksym_table)
400 0 : ABI_FREE(symrec_fm)
401 0 : ABI_FREE(fm2symrec)
402 :
403 : ! Divide the operations into classes.
404 0 : ABI_MALLOC(dum_symafm, (esymm%nsym_gk))
405 0 : dum_symafm = 1
406 :
407 : ! Check group closure
408 0 : call sg_multable(esymm%nsym_gk, dum_symafm, sgk, grp_ierr)
409 0 : ABI_CHECK_IEQ(grp_ierr, 0, "sg_multable failed")
410 0 : ABI_FREE(dum_symafm)
411 :
412 0 : ABI_MALLOC(tmp_nelements, (esymm%nsym_gk))
413 0 : ABI_MALLOC(elements_idx, (esymm%nsym_gk, esymm%nsym_gk))
414 :
415 0 : call get_classes(esymm%nsym_gk, sgk, esymm%nclass, tmp_nelements, elements_idx)
416 :
417 0 : ABI_MALLOC(esymm%nelements, (esymm%nclass))
418 0 : esymm%nelements = tmp_nelements(1:esymm%nclass)
419 0 : ABI_FREE(tmp_nelements)
420 :
421 : ! From the list of symmetry operations and the lattice vectors, determine the
422 : ! Bravais information including the holohedry, the centering, the coordinate of
423 : ! the primitive vectors in the conventional vectors, as well as the point group,
424 0 : msym=192; if (allocated(Cryst%symrec)) msym=size(Cryst%symrec,3)
425 0 : ABI_MALLOC(tmp_symrec,(3,3,msym))
426 0 : tmp_symrec(:,:,1:esymm%nsym_gk)=sgk
427 :
428 0 : call symbrav(bravais,msym,esymm%nsym_gk,ptgroup,Cryst%gprimd,tmp_symrec,tolsym,axis=sym_axis)
429 :
430 0 : ABI_FREE(tmp_symrec)
431 :
432 0 : write(std_out,'(a)')" symptgroup returned point group: "//TRIM(ptgroup)
433 0 : write(std_out,'(a,i2)')" iholohedry ",bravais(1)
434 0 : write(std_out,'(a,i2)')" center ",bravais(2)
435 0 : write(std_out,'(a,9i3)')" gprimd in the axes of the conventional bravais lattice (*2 if center/=0)",bravais(3:11)
436 0 : write(std_out,'(a,3i3)')" sym_axis ",sym_axis
437 :
438 : ! Branching:
439 : ! 1) If the little group is not symmorphic_at_zoneborder we can
440 : ! classify the states using the irreducible representation of the point group.
441 : !
442 : ! 2) If the little group is symmorphic_at_zoneborder, we have to rely on
443 : ! an external database retrieved from the Bilbao server in order to classify the states.
444 : ! If the file is not available, we only know the number of classes but neither their
445 : ! character nor the dimension of the irreducible representation.
446 : !
447 0 : if (esymm%nonsymmorphic_at_zoneborder) then
448 :
449 0 : spgroup=0
450 0 : chkprim=1 ! Cell must be primitive.
451 : !call symlatt(bravais,std_out,msym,nptsym,ptsymrel,rprimd,tolsym)
452 : !call symspgr(bravais,Cryst%nsym,spgroup,Cryst%symrel,Cryst%tnons,tolsym)
453 :
454 : !call symanal(bravais,chkprim,genafm,msym,nsym,ptgroupma,rprimd,spgroup,symafm,symrel,tnons,tolsym)
455 :
456 0 : call int2char10(spgroup, spgroup_str)
457 0 : lgroup_fname = "lgroup_"//TRIM(spgroup_str)
458 :
459 0 : if (file_exists(lgroup_fname)) then
460 0 : ABI_ERROR("Not coded")
461 : ! Read little groups from the external database.
462 : !% call init_groupk_from_file(Lgrp,spgroup,lgroup_fname,ierr)
463 :
464 : ! Save the irreducible representations in esymm.
465 : ! Reorder symmetries such that they correspond to the Bilbao database.
466 : !% allocate(esymm%Ref_irreps(esymm%nclass))
467 : !% call copy_irrep(Irreps, esymm%Ref_irreps)
468 :
469 : else
470 : write(msg,'(7a)')&
471 0 : "Non-symmorphic small group and zone border. ",ch10,&
472 0 : "External file: ",TRIM(lgroup_fname)," containing Bilbao tables not found ",ch10,&
473 0 : "Character analysis cannot be performed. Accidental degeneracies cannot be detected. "
474 0 : ABI_WARNING(msg)
475 :
476 0 : esymm%has_chtabs = .FALSE.
477 :
478 : ! Reorder indices such that symmetries are packed in classes.
479 0 : ABI_MALLOC(new_idx,(esymm%nsym_gk))
480 0 : ABI_MALLOC(new_g0,(3,esymm%nsym_gk))
481 0 : new_g0=0; iord = 0
482 0 : do icls=1,esymm%nclass
483 0 : do iel=1,esymm%nelements(icls)
484 0 : iord = iord+1
485 0 : jsym = elements_idx(iel,icls)
486 0 : new_idx(iord) = esymm%sgk2symrec(jsym)
487 0 : new_g0(:,iord) = esymm%g0(:,jsym)
488 : end do
489 : end do
490 :
491 0 : esymm%sgk2symrec = new_idx
492 0 : esymm%g0 = new_g0
493 :
494 0 : ABI_FREE(new_idx)
495 0 : ABI_FREE(new_g0)
496 : end if ! file exists
497 :
498 : else
499 : !
500 : ! **** This part is still under development. It might not work for particular ****
501 : ! **** orientations of the unit cell or particular lattices. ****
502 : !
503 : ! The symmetries in the Bilbao database refer to the conventional unit cells.
504 : ! Therefore we have to map the abinit symmetries (in reduced coordinates)
505 : ! onto the Bilbao dataset. Bilbao standard settings are:
506 : !
507 : ! * unique axis b (cell choice 1) for space groups withing the monoclinic system
508 : ! * obverse triple hexagonal unit cell R space groups.
509 : ! * origin choice two - inversion center at (0, 0, 0) - for the centrosymmetric
510 : ! space groups for which there are two origins choices, within the
511 : ! orthorombic, tetragonal and cubic system.
512 :
513 : ! 1) Retrieve the rotation matrices and the irreducible representations (Bilbao setting).
514 0 : call point_group_init(Ptg,ptgroup)
515 :
516 0 : esymm%has_chtabs = .TRUE.
517 0 : ABI_CHECK(esymm%nclass == Ptg%nclass,"esymm%nclass/=Ptg%nclass!")
518 :
519 0 : do icls=1,esymm%nclass ! FIXME this is awful, should be done in a cleaner way.
520 0 : esymm%nelements(icls)=Ptg%class_ids(2,icls) - Ptg%class_ids(1,icls) + 1
521 : end do
522 :
523 : ! 2) Generate the symmetry operations in the conventional vector coordinates.
524 0 : conv_gprimd(:,1)=bravais(3:5)
525 0 : conv_gprimd(:,2)=bravais(6:8)
526 0 : conv_gprimd(:,3)=bravais(9:11)
527 :
528 0 : axes = conv_gprimd
529 0 : call matr3inv(conv_gprimd,axes) !; axes=TRANSPOSE(axes)
530 :
531 0 : conv_gprimd=MATMUL(Cryst%gprimd,TRANSPOSE(axes))
532 : !conv_gprimd=MATMUL(axes,Cryst%gprimd)
533 : !conv_gprimd=MATMUL(TRANSPOSE(axes),Cryst%gprimd)
534 : !write(std_out,*)"conv_gprimd:", conv_gprimd
535 :
536 0 : ptgroup_name = ADJUSTL(ptgroup)
537 :
538 0 : select case (ptgroup_name)
539 :
540 : case ("3m","-3m")
541 0 : call wrtout(std_out," Changing the conventional cell: rhombohedral --> triple hexagonal")
542 : ! Transformation matrices: primitive rhombohedral --> triple hexagonal cell obverse setting. Table 5.1.3.1 ITA page 81.
543 0 : pmat1 = RESHAPE( (/ 1,-1, 0, 0, 1,-1, 1, 1, 1/), (/3,3/) ) ! R1
544 : pmat2 = RESHAPE( (/ 0, 1,-1,-1, 0, 1, 1, 1, 1/), (/3,3/) ) ! R2
545 : pmat3 = RESHAPE( (/-1, 0, 1, 1,-1, 0, 1, 1, 1/), (/3,3/) ) ! R3
546 : pmat4 = RESHAPE( (/-1, 1, 0, 0,-1, 1, 1, 1, 1/), (/3,3/) ) ! R1 reverse setting.
547 : pmat5 = RESHAPE( (/ 0,-1, 1, 1, 0,-1, 1, 1, 1/), (/3,3/) ) ! R2 reverse setting.
548 : pmat6 = RESHAPE( (/ 1, 0,-1,-1, 1, 0, 1, 1, 1/), (/3,3/) ) ! R3 reverse setting.
549 0 : conv_gprimd = MATMUL(conv_gprimd,pmat1)
550 : !conv_gprimd = MATMUL(conv_gprimd,pmat2)
551 : !conv_gprimd = MATMUL(conv_gprimd,pmat3)
552 : !conv_gprimd = MATMUL(conv_gprimd,pmat4)
553 : !conv_gprimd = MATMUL(conv_gprimd,pmat5)
554 : !conv_gprimd = MATMUL(conv_gprimd,pmat6)
555 : !write(std_out,*)" New conv_gprimd:", conv_gprimd
556 :
557 : case ("mm2")
558 0 : call wrtout(std_out," Changing the conventional cell: unconventional orthorhombic setting --> conventional")
559 : ! Transformation matrices: unconvential orthorhombic --> conventional orthorhombic. Table 5.1.3.1 ITA page 81.
560 : pmat1 = RESHAPE( (/ 0, 1, 0, 1, 0, 0, 0, 0,-1/), (/3,3/) ) ! ( b, a,-c) --> (a,b,c)
561 0 : pmat2 = RESHAPE( (/ 0, 1, 0, 0, 0, 1, 1, 0, 0/), (/3,3/) ) ! ( c, a, b) --> (a,b,c)
562 : pmat3 = RESHAPE( (/ 0, 0, 1, 0, 1, 0,-1, 0, 0/), (/3,3/) ) ! (-c, b, a) --> (a,b,c)
563 : pmat4 = RESHAPE( (/ 0, 0, 1, 1, 0, 0, 0, 1, 0/), (/3,3/) ) ! ( b, c, a) --> (a,b,c)
564 : pmat5 = RESHAPE( (/ 1, 0, 0, 0, 0, 1, 0,-1, 0/), (/3,3/) ) ! ( a,-c, b) --> (a,b,c)
565 0 : conv_gprimd = MATMUL(conv_gprimd,pmat2)
566 : !write(std_out,*)" New conv_gprimd:", conv_gprimd
567 : case default
568 0 : continue
569 : end select
570 :
571 0 : ABI_MALLOC(conv_symrec,(3,3,esymm%nsym_gk))
572 0 : conv_symrec = sgk
573 :
574 : !axes=zero; axes(1,1)=one ; axes(2,2)=one ; axes(3,3)=one
575 : !call symrelrot(esymm%nsym_gk,conv_gprimd,axes,conv_symrec,tolsym)
576 0 : call symrelrot(esymm%nsym_gk,Cryst%gprimd,conv_gprimd,conv_symrec,tolsym)
577 :
578 : ! 3) Reorder indices such that symmetries are packed in classes.
579 0 : ABI_MALLOC(found,(esymm%nsym_gk))
580 0 : ABI_MALLOC(new_idx,(esymm%nsym_gk))
581 0 : ABI_MALLOC(new_g0,(3,esymm%nsym_gk))
582 0 : new_g0=0; found=0
583 :
584 0 : do isym=1,esymm%nsym_gk
585 0 : do jsym=1,esymm%nsym_gk
586 0 : if (ALL(Ptg%sym(:,:,isym) == conv_symrec(:,:,jsym) )) then
587 0 : found(isym) = found(isym) + 1
588 0 : new_idx(isym) = esymm%sgk2symrec(jsym)
589 0 : new_g0(:,isym) = esymm%g0(:,jsym)
590 : !EXIT
591 : end if
592 : end do
593 : end do
594 : !
595 : ! DEBUGGING SECTION
596 : !do isym=1,esymm%nsym_gk
597 : ! jsym=esymm%sgk2symrec(isym)
598 : ! call print_symmetries(1,Cryst%symrec(:,:,jsym),Cryst%tnons(:,jsym),Cryst%symafm(jsym))
599 : ! write(std_out,*)esymm%g0(:,isym)
600 : !end do
601 :
602 0 : if ( Ptg%nsym/=esymm%nsym_gk .or. ANY(found/=1) ) then
603 : !write(std_out,*)Ptg%nsym, esymm%nsym_gk
604 : !write(std_out,'(a,(i2))')" found = ",found
605 0 : write(std_out,*)" Ptg%sym list, conv_symrec list, found Ptg% "
606 0 : do isym=1,Ptg%nsym
607 0 : write(std_out,'(a,i2,a,9i2,4x,a,9i2)')" found ",found(isym)," Ptg ",Ptg%sym(:,:,isym),"conv_symrec ",conv_symrec(:,:,isym)
608 : end do
609 0 : msg = " sgk and esymm%Ptg are inconsistent. Check tables or source"
610 0 : ABI_WARNING(msg)
611 0 : esymm%err_msg = msg(1:500)
612 0 : esymm%err_status = ESYM_PTG_WRONG_MAPPING
613 0 : esymm%has_chtabs = .FALSE.
614 :
615 : else ! Reorder symmetries.
616 0 : esymm%sgk2symrec = new_idx
617 0 : esymm%g0 = new_g0
618 : end if
619 :
620 0 : ABI_FREE(new_idx)
621 0 : ABI_FREE(new_g0)
622 0 : ABI_FREE(found)
623 0 : ABI_FREE(conv_symrec)
624 :
625 0 : if (esymm%has_chtabs) then
626 : ! Multiply the point group irreps by e^{-ik.\tau} to have the irreps of the little group.
627 : ! Store the results in esymm%Ref_irreps so that one can classify the states afterwards.
628 0 : ABI_MALLOC(esymm%Ref_irreps,(esymm%nclass))
629 0 : ABI_MALLOC(phase_mkt,(esymm%nsym_gk))
630 :
631 0 : do isym_gk=1,esymm%nsym_gk
632 0 : isym = esymm%sgk2symrec(isym_gk)
633 0 : mkt = -two_pi * DOT_PRODUCT(esymm%kpt, Cryst%tnons(:,isym))
634 0 : phase_mkt(isym_gk) = CMPLX(DCOS(mkt), DSIN(mkt))
635 : end do
636 :
637 0 : call copy_irrep(Ptg%Irreps, esymm%Ref_irreps, phase_mkt)
638 0 : ABI_FREE(phase_mkt)
639 : end if
640 :
641 : #if 0
642 : ! Herring test requires the evaluation of the expression:
643 : !
644 : ! sum_{S,\tau} \chi^{k,\alpha} ({S|\tau}^2)
645 : !
646 : ! where Sk = -k + g0, and \chi is the trace of the \alpha-th
647 : ! irreducible representation of the little group of k.
648 : ! \chi^{k,\alpha} = e^{-ik.\tau} \chi(\alpha) provided that
649 : ! we are not at zone border with a non-symmorphic operation.
650 : ! The expression is always real and it can only be equal to \pm Ptg%nsym or zero.
651 : ! FIXME this part has to be rewritten from scratch.
652 : !if (esymm%err_status/=esymm_NOERROR) then
653 : ! write(std_out,*)" Skipping Herring test"
654 : ! goto 110
655 : !end if
656 :
657 : if (esymm%can_use_tr) then
658 : ABI_MALLOC(her_test,(esymm%nclass))
659 :
660 : ABI_MALLOC(tr_conv_symrec,(3,3,esymm%nsym_trgk))
661 : do isym_tr=1,esymm%nsym_trgk
662 : isym = esymm%tr_sgk2symrec(isym_tr)
663 : tr_conv_symrec(:,:,isym_tr)=Cryst%symrec(:,:,isym)
664 : end do
665 :
666 : call symrelrot(esymm%nsym_trgk,Cryst%gprimd,conv_gprimd,tr_conv_symrec_tr,tolsym)
667 :
668 : do isym_tr=1,esymm%nsym_trgk
669 : isym = esymm%tr_sgk2symrec(isym_tr)
670 : !rot2 = MATMUL(tr_sgk(:,:,isym),tr_sgk(:,:,isym))
671 : !tau2 = MATMUL(tr_sgk(:,:,isym),Cryst%tnons(:,isym)) + Cryst%tnons(:,isym)
672 :
673 : rot2 = MATMUL(tr_conv_symrec(:,:,isym_tr),tr_conv_symrec(:,:,isym_tr))
674 : tau2 = MATMUL(tr_conv_symrec(:,:,isym_tr),Cryst%tnons(:,isym)) + Cryst%tnons(:,isym)
675 :
676 : phase_k = EXP(-j_dpc*two_pi*DOT_PRODUCT(kpoint,tau2))
677 : call locate_sym(Ptg,rot2,isym2,icls2)
678 :
679 : do irp=1,esymm%nclass
680 : her_test(irp) = her_test(irp) + phase_k * Ptg%Irreps(irp)%trace(icls2)
681 : end do
682 : end do
683 :
684 : ABI_FREE(tr_conv_symrec)
685 :
686 : ! FIXME
687 : ABI_MALLOC(esymm%herring_test,(esymm%nclass))
688 :
689 : do irp=1,esymm%nclass
690 : if ( ABS(her_test(irp) - Ptg%nsym) < tol6 ) then
691 : esymm%herring_test(irp) = +1
692 : else if ( ABS(her_test(irp)) < tol6 ) then
693 : esymm%herring_test(irp) = 0
694 : else if ( ABS(her_test(irp) + Ptg%nsym) < tol6 ) then
695 : esymm%herring_test(irp) = -1
696 : else
697 : write(msg,'(a,i0,2a,i0,a,i0)')&
698 : "Herring test for the irreducible representation number ",irp,ch10,&
699 : "gave ",esymm%herring_test(irp),", while it should be 0 or +- ",Ptg%nsym
700 : ABI_WARNING(msg)
701 : esymm%err_msg = msg
702 : esymm%err_status = ESYMM_HERRING_WRONG_TEST
703 : end if
704 : end do
705 :
706 : ABI_FREE(her_test)
707 : end if ! can_use_tr
708 : #endif
709 : !
710 : ! Final check
711 : !allocate(mtab(esymm%nsym_gk,esymm%nsym_gk))
712 : !call mult_table(esymm%nsym_gk,Ptg%sym,mtab)
713 :
714 : !do isym=1,esymm%nsym_gk
715 : ! isym1 = esymm%sgk2symrec(isym)
716 : ! do jsym=1,esymm%nsym_gk
717 : ! isym2 = esymm%sgk2symrec(jsym)
718 : ! rot2 = MATMUL(Cryst%symrec(:,:,isym1),Cryst%symrec(:,:,isym2))
719 :
720 : ! iprod = mtab(isym,jsym)
721 :
722 : ! do irp=1,esymm%nclass
723 : ! dim_irrep = Ptg%Irreps(irp)%dim
724 : ! allocate(mat_test(dim_irrep,dim_irrep))
725 : ! mat_test = Ptg%Irreps(irp)%mat(:,:,isym) * Ptg%Irreps(irp)%mat(:,:,jsym)
726 : ! !call locate_sym(Ptg,rot2,isym2,icls2)
727 : ! write(std_out,*)mat_test - Ptg%Irreps(irp)%mat(:,:,iprod)
728 : ! deallocate(mat_test)
729 : ! end do
730 : !
731 : ! end do
732 : !end do
733 : !
734 : !deallocate(mtab)
735 : end if
736 :
737 0 : ABI_FREE(sgk)
738 0 : ABI_FREE(tr_sgk)
739 0 : ABI_FREE(elements_idx)
740 :
741 : !% allocate(esymm%irrep2b(0:esymm%nclass))
742 : !% call nullify_coeff(esymm%irrep2b)
743 : !
744 : ! 1) Allocate space for the irreducible representations.
745 :
746 : ! 2) Try to determine if we are in presence of an accidental degeneracy. Sufficient condition:
747 : ! There exists a set of degenerate states whose dimension is greater than the dimension
748 : ! of the irreducible representations of the point group. The check can be done only
749 : ! if Character tables are available.
750 :
751 0 : if (esymm%has_chtabs) then
752 0 : ABI_MALLOC(dim_irreps,(esymm%nclass))
753 0 : dim_irreps = (/(esymm%Ref_irreps(irp)%dim, irp=1,esymm%nclass)/)
754 : end if
755 :
756 0 : nacc_deg=0
757 0 : ABI_MALLOC(esymm%degs_dim,(esymm%ndegs))
758 0 : ABI_MALLOC(esymm%Calc_irreps,(esymm%ndegs))
759 :
760 0 : if (esymm%can_use_tr) then
761 0 : ABI_MALLOC(esymm%trCalc_irreps,(esymm%ndegs))
762 : end if
763 :
764 0 : do idg=1,esymm%ndegs
765 0 : dim_degs=esymm%degs_bounds(2,idg)-esymm%degs_bounds(1,idg)+1
766 :
767 0 : if (esymm%has_chtabs) then
768 0 : if (ALL(dim_degs /= dim_irreps)) then ! An accidental degeneracy is present.
769 0 : nacc_deg=nacc_deg+1
770 : end if
771 : end if
772 :
773 0 : esymm%degs_dim(idg) = dim_degs
774 :
775 0 : call esymm%Calc_irreps(idg)%init(esymm%nsym_gk, dim_degs)
776 0 : if (esymm%can_use_tr) call esymm%trCalc_irreps(idg)%init(esymm%nsym_trgk, dim_degs)
777 : end do ! idg
778 :
779 0 : if (esymm%has_chtabs) then
780 0 : ABI_FREE(dim_irreps)
781 0 : if (nacc_deg /= 0) then
782 0 : write(msg,'(a,i0,a)')" Detected ",nacc_deg," accidental degeneracies."
783 0 : ABI_WARNING(msg)
784 0 : esymm%err_status = ESYM_ACCDEG_ERROR
785 : ! TODO this should signal to the caller that we have to decompose the calculated representation.
786 0 : esymm%err_msg = msg(1:500)
787 : end if
788 : end if
789 :
790 :
791 0 : ABI_FREE(dummy_symafm)
792 0 : call Ptg%free()
793 :
794 : DBG_EXIT("COLL")
795 :
796 0 : end subroutine esymm_init
797 : !!***
798 :
799 : !----------------------------------------------------------------------
800 :
801 : !!****f* m_esymm/esymm_print
802 : !! NAME
803 : !! esymm_print
804 : !!
805 : !! FUNCTION
806 : !!
807 : !! INPUTS
808 : !!
809 : !! OUTPUT
810 : !! only printing
811 : !!
812 : !! SOURCE
813 :
814 0 : subroutine esymm_print(esymm, units, prtvol)
815 :
816 : !Arguments ------------------------------------
817 : class(esymm_t),intent(in) :: esymm
818 : integer,intent(in) :: units(:), prtvol
819 :
820 : !Local variables-------------------------------
821 : integer :: icl, idg, irr_idx, nstates, nunknown, istart, istop, ii
822 : character(len=1000) :: fmt, msg, msg0
823 : ! *********************************************************************
824 :
825 0 : write(fmt, *)'(2a,3f8.4,3a,i4,2a,i3,2a,i2,2a,i2,a,',esymm%nclass,'i2,a)'
826 0 : write(msg, fmt) ch10,&
827 0 : ' ===== Character of bands at k-point: ',esymm%kpt,' ===== ',ch10,&
828 0 : ' Total number of bands analyzed .................. ',esymm%nbnds,ch10,&
829 0 : ' Number of degenerate sets detected .............. ',esymm%ndegs,ch10,&
830 0 : ' Number of operations in the little group of k ... ',esymm%nsym_gk,ch10,&
831 0 : ' Number of classes (irreps) in the group of k .... ',esymm%nclass,' (',(esymm%nelements(icl),icl=1,esymm%nclass),' )'
832 0 : call wrtout(units, msg)
833 :
834 0 : if (esymm%nonsymmorphic_at_zoneborder) then
835 0 : call wrtout(units," Non-symmorphic small group at zone border. Character analysis not available ")
836 : end if
837 :
838 0 : if (esymm_failed(esymm)) then
839 0 : write(std_out,'(3a)')"Band classification algorithm failed with the error:",ch10,TRIM(esymm%err_msg)
840 0 : write(msg,'(3a)')"Band classification algorithm failed with the error:",ch10,TRIM(esymm%err_msg)
841 0 : call wrtout(units, msg)
842 : end if
843 :
844 : !nunknown=0
845 : !do iband=1,esymm%nbnds
846 : ! irr_idx = esymm%b2irrep(iband)
847 : ! if (irr_idx /= 0) then
848 : ! if ( esymm%has_chtabs) irr_name = esymm%Ref_Irreps(irr_idx)%name
849 : ! if (.not.esymm%has_chtabs) write(irr_name,'(i0)')irr_idx ! use the index instead of the name.
850 : ! else
851 : ! irr_name = "???"
852 : ! nunknown = nunknown +1
853 : ! end if
854 : ! write(msg,'(a,i3,2a)')' Band ',iband,' belongs to irrep ',TRIM(irr_name)
855 : ! call wrtout(units, msg)
856 : !end do
857 :
858 0 : do irr_idx=1,esymm%nclass
859 0 : nstates = size(esymm%irrep2b(irr_idx)%value)
860 0 : if (esymm%has_chtabs) then
861 0 : write(msg0,'(a,i0,3a)')" Found ",nstates," states with character ",TRIM(esymm%Ref_irreps(irr_idx)%name),": "
862 : else
863 0 : write(msg0,'(2(a,i0),a)')" Found ",nstates," states with character index ",irr_idx,": "
864 : end if
865 0 : do istart=1,nstates,20
866 0 : istop=istart+11; if (istop>nstates) istop=nstates
867 0 : write(msg,'(20(1x,i0))')(esymm%irrep2b(irr_idx)%value(ii), ii=istart,istop)
868 0 : if (istart==1) msg = TRIM(msg0)//TRIM(msg)
869 0 : if (istart/=1) msg = " "//TRIM(msg)
870 0 : call wrtout(units, msg)
871 : end do
872 : end do
873 :
874 0 : nunknown = size(esymm%irrep2b(0)%value)
875 0 : if (nunknown > 0) then
876 0 : write(msg0,'(a,i0,a)')" WARNING: ",nunknown," states have not been classified:"
877 0 : do istart=1,nunknown,20
878 0 : istop=istart+11; if (istop>nunknown) istop=nunknown
879 0 : write(msg,'(20(1x,i0))')(esymm%irrep2b(0)%value(ii), ii=istart,istop)
880 0 : if (istart==1) msg = TRIM(msg0)//TRIM(msg)
881 0 : if (istart/=1) msg = " "//TRIM(msg)
882 0 : call wrtout(units, msg)
883 : end do
884 : end if
885 :
886 0 : if (prtvol > 0 .or. nunknown > 0 .or. .not.esymm%has_chtabs) then
887 : ! print the calculated character table.
888 0 : call wrtout(units,ch10//" Calculated character table ")
889 : !write(fmt,*)'(i2,a,i2,1x,',esymm%nclass,'(a,2f6.3),a)'
890 0 : write(fmt,*)'(i2,a,i2,1x,',esymm%nclass,'(a,2f5.2),a)'
891 0 : do idg=1,esymm%ndegs
892 : write(msg, fmt) &
893 0 : esymm%degs_bounds(1,idg),'-',esymm%degs_bounds(2,idg),&
894 0 : ('|',esymm%Calc_irreps(idg)%trace(esymm%nelements(icl)), icl=1,esymm%nclass),'|'
895 0 : call wrtout(units, msg)
896 : end do
897 : end if
898 :
899 0 : end subroutine esymm_print
900 : !!***
901 :
902 : !----------------------------------------------------------------------
903 :
904 : !!****f* m_esymm/esymm_free_0D
905 : !! NAME
906 : !! esymm_free_0D
907 : !!
908 : !! FUNCTION
909 : !! Deallocate the memory allocated in the esymm_t datatype (scalar version)
910 : !!
911 : !! SOURCE
912 :
913 1232 : subroutine esymm_free_0D(esymm)
914 :
915 : !Arguments ------------------------------------
916 : class(esymm_t),intent(inout) :: esymm
917 :
918 : !Local variables ------------------------------
919 : integer :: ii
920 : ! *************************************************************************
921 :
922 1232 : ABI_SFREE(esymm%g0)
923 1232 : ABI_SFREE(esymm%tr_g0)
924 1232 : ABI_SFREE(esymm%nelements)
925 1232 : ABI_SFREE(esymm%sgk2symrec)
926 1232 : ABI_SFREE(esymm%tr_sgk2symrec)
927 1232 : ABI_SFREE(esymm%herring_test)
928 1232 : ABI_SFREE(esymm%b2irrep)
929 1232 : ABI_SFREE(esymm%degs_bounds)
930 1232 : ABI_SFREE(esymm%degs_dim)
931 :
932 1232 : if (allocated(esymm%irrep2b)) then
933 0 : do ii=LBOUND(esymm%irrep2b,DIM=1),UBOUND(esymm%irrep2b,DIM=1)
934 0 : ABI_FREE(esymm%irrep2b(ii)%value)
935 : end do
936 0 : ABI_FREE(esymm%irrep2b)
937 : end if
938 :
939 1232 : if (allocated(esymm%Calc_irreps)) then
940 0 : call irrep_free(esymm%Calc_irreps)
941 0 : ABI_FREE(esymm%Calc_irreps)
942 : end if
943 1232 : if (allocated(esymm%trCalc_irreps)) then
944 0 : call irrep_free(esymm%trCalc_irreps)
945 0 : ABI_FREE(esymm%trCalc_irreps)
946 : end if
947 1232 : if (allocated(esymm%Ref_irreps)) then
948 0 : call irrep_free(esymm%Ref_irreps)
949 0 : ABI_FREE(esymm%Ref_irreps)
950 : end if
951 :
952 1232 : end subroutine esymm_free_0D
953 : !!***
954 :
955 : !----------------------------------------------------------------------
956 :
957 : !!****f* m_esymm/esymm_free_2D
958 : !! NAME
959 : !! esymm_free_2D
960 : !!
961 : !! FUNCTION
962 : !! Deallocate the memory allocated in the esymm_t datatype (2D version)
963 : !!
964 : !! SOURCE
965 :
966 201 : subroutine esymm_free_2D(esymm)
967 :
968 : !Arguments ------------------------------------
969 : class(esymm_t),intent(inout) :: esymm(:,:)
970 :
971 : !Local variables ------------------------------
972 : integer :: id1,id2
973 : ! *************************************************************************
974 :
975 406 : do id2=1,SIZE(esymm,DIM=2)
976 1638 : do id1=1,SIZE(esymm,DIM=1)
977 1437 : call esymm_free_0D(esymm(id1,id2))
978 : end do
979 : end do
980 :
981 201 : end subroutine esymm_free_2D
982 : !!***
983 :
984 : !----------------------------------------------------------------------
985 :
986 : !!****f* m_esymm/esymm_finalize
987 : !! NAME
988 : !! esymm_finalize
989 : !!
990 : !! FUNCTION
991 : !!
992 : !! INPUTS
993 : !!
994 : !! SOURCE
995 :
996 0 : subroutine esymm_finalize(esymm, prtvol)
997 :
998 : !Arguments ------------------------------------
999 : !scalars
1000 : class(esymm_t),target,intent(inout) :: esymm
1001 : integer,intent(in) :: prtvol
1002 :
1003 : !Local variables-------------------------------
1004 : integer :: idg,ib1,ib2,idx,nunknown,dg_dim
1005 : integer :: try,irep,nitems,nseen,isn
1006 : integer :: isym,idg1,idg2,dim_mat,irr_idx2,irr_idx1
1007 : real(dp),parameter :: TOL_TRACE=0.1_dp,TOL_ORTHO=0.1_dp,TOL_UNITARY=0.1_dp ! Large tolerance is needed to avoid problems.
1008 : !real(dp),parameter :: TOL_TRACE=0.01_dp,TOL_ORTHO=0.01_dp,TOL_UNITARY=0.01_dp ! Large tolerance is needed to avoid problems.
1009 : !real(dp),parameter :: TOL_TRACE=tol3,TOL_ORTHO=tol3,TOL_UNITARY=tol3 ! Large tolerance is needed to avoid problems.
1010 : real(dp) :: uerr,max_err
1011 : complex(dp) :: ctest
1012 : logical :: isnew
1013 : character(len=500) :: msg
1014 : !arrays
1015 0 : integer,allocatable :: dims_seen(:)
1016 0 : complex(dp),allocatable :: traces_seen(:,:), cidentity(:,:)
1017 0 : complex(dp),pointer :: trace(:), calc_mat(:,:),trace1(:),trace2(:)
1018 : ! *************************************************************************
1019 :
1020 : ! Each band is initialized as "Unknown".
1021 0 : esymm%b2irrep = 0
1022 :
1023 : ! Force the matrices to be unitary.
1024 0 : call polish_irreps(esymm%Calc_irreps)
1025 :
1026 0 : if (.not. esymm%has_chtabs) then
1027 :
1028 : write(msg,'(5a)')&
1029 0 : "Reference character table not available. ",ch10,&
1030 0 : "Symmetry analysis not available. Using heuristic method to classify the states.",ch10,&
1031 0 : "It might not work, especially if accidental degeneracies are present."
1032 0 : ABI_WARNING(msg)
1033 :
1034 : ! The simplest thing we can do here is using the calculated matrices to get the
1035 : ! character and comparing the results hoping everything is OK.
1036 0 : ABI_MALLOC(traces_seen,(esymm%nsym_gk,esymm%ndegs))
1037 0 : ABI_MALLOC(dims_seen,(esymm%ndegs))
1038 :
1039 0 : traces_seen=czero; nseen=1
1040 0 : traces_seen(:,1) = esymm%Calc_irreps(1)%trace
1041 0 : dims_seen(1) = esymm%Calc_irreps(1)%dim
1042 :
1043 0 : do idg=2,esymm%ndegs
1044 0 : dg_dim = esymm%Calc_irreps(idg)%dim
1045 0 : trace => esymm%Calc_irreps(idg)%trace
1046 0 : isnew=.TRUE.
1047 0 : do isn=1,nseen
1048 0 : if (ALL (ABS(trace - traces_seen(:,isn)) < TOL_TRACE) ) then
1049 : isnew=.FALSE.; EXIT
1050 : end if
1051 : end do
1052 :
1053 0 : if (isnew) then
1054 0 : nseen = nseen+1
1055 0 : traces_seen(:,nseen) = trace
1056 0 : dims_seen(nseen) = dg_dim
1057 : end if
1058 : end do
1059 :
1060 0 : if (nseen > esymm%nclass) then
1061 : write(msg, '(3a)') &
1062 0 : "The number of different calculated traces is found to be greater than nclasses!",ch10,&
1063 0 : "Heuristic method clearly failed. Symmetry analysis cannot be performed."
1064 0 : ABI_WARNING(msg)
1065 0 : esymm%err_status = ESYM_HEUR_WRONG_NCLASSES
1066 0 : esymm%err_msg = msg
1067 :
1068 0 : do isn=1,nseen
1069 0 : write(msg,'(a,i0)')" Representation: ",isn
1070 0 : call wrtout(std_out,msg)
1071 0 : call print_arr([std_out], traces_seen(:,isn),max_r=esymm%nsym_gk)
1072 : end do
1073 :
1074 : else ! It seems that the Heuristic method succeeded.
1075 0 : do idg=1,esymm%ndegs
1076 0 : ib1=esymm%degs_bounds(1,idg)
1077 0 : ib2=esymm%degs_bounds(2,idg)
1078 0 : trace => esymm%Calc_irreps(idg)%trace
1079 0 : do isn=1,nseen
1080 0 : if (ALL (ABS(trace - traces_seen(:,isn)) < TOL_TRACE) ) then
1081 0 : esymm%b2irrep(ib1:ib2)=isn
1082 0 : if (esymm%Calc_irreps(idg)%dim /= dims_seen(isn)) then
1083 : write(msg,'(3a)')&
1084 0 : "Found two set of degenerate states with same character but different dimension!",ch10,&
1085 0 : "heuristic method clearly failed. Symmetry analysis cannot be performed."
1086 0 : ABI_ERROR(msg)
1087 0 : esymm%err_status = ESYM_HEUR_WRONG_DIMS
1088 0 : esymm%err_msg = msg
1089 : end if
1090 : EXIT
1091 : end if
1092 : end do
1093 : end do
1094 : end if
1095 :
1096 0 : ABI_FREE(traces_seen)
1097 0 : ABI_FREE(dims_seen)
1098 :
1099 : else
1100 : ! Search in the lookup table definining the irreducible representation
1101 0 : nunknown = 0
1102 0 : do idg=1,esymm%ndegs
1103 :
1104 0 : ib1=esymm%degs_bounds(1,idg)
1105 0 : ib2=esymm%degs_bounds(2,idg)
1106 0 : trace => esymm%Calc_irreps(idg)%trace
1107 :
1108 0 : try = which_irrep(esymm, trace, tol3)
1109 0 : if (try==0) try = which_irrep(esymm, trace, 0.1_dp) ! try again with increased tolerance.
1110 0 : if (try/=0) then
1111 0 : esymm%b2irrep(ib1:ib2)=try
1112 : else
1113 0 : esymm%b2irrep(ib1:ib2)=0
1114 0 : nunknown = nunknown + (ib2-ib1+1)
1115 : end if
1116 : end do
1117 : end if
1118 :
1119 : ! %irrep2b(0)) gives the indices of the states that have not been classified.
1120 0 : ABI_MALLOC(esymm%irrep2b,(0:esymm%nclass))
1121 : !write(std_out,*)"b2irrep",esymm%b2irrep
1122 :
1123 0 : do irep=0,esymm%nclass
1124 0 : nitems = COUNT(esymm%b2irrep==irep)
1125 0 : ABI_MALLOC(esymm%irrep2b(irep)%value,(nitems))
1126 0 : idx=0
1127 0 : do ib1=1,esymm%nbnds
1128 0 : if (esymm%b2irrep(ib1) == irep) then
1129 0 : idx = idx + 1
1130 0 : esymm%irrep2b(irep)%value(idx) = ib1
1131 : end if
1132 : end do
1133 : end do
1134 :
1135 0 : if (size(esymm%irrep2b(0)%value) /= 0) then
1136 0 : write(msg,'(a,i0,a)')" Band classification algorithm was not able to classify ",size(esymm%irrep2b(0)%value)," states."
1137 0 : ABI_WARNING(msg)
1138 0 : esymm%err_status = ESYM_CLASSIFICATION_ERROR
1139 0 : esymm%err_msg = msg
1140 : end if
1141 :
1142 : ! Test basic properties of irreducible representations.
1143 0 : if (.not. esymm%failed()) then
1144 : ! 1) \sum_R \chi^*_a(R)\chi_b(R)= N_R \delta_{ab}
1145 : !call wrtout(std_out," \sum_R \chi^*_a(R)\chi_b(R) = N_R \delta_{ab} ")
1146 0 : max_err=zero
1147 0 : do idg2=1,esymm%ndegs
1148 0 : trace2 => esymm%Calc_irreps(idg2)%trace(1:esymm%nsym_gk)
1149 0 : ib2 = esymm%degs_bounds(1,idg2)
1150 0 : irr_idx2 = esymm%b2irrep(ib2)
1151 0 : if (irr_idx2 == 0) CYCLE
1152 :
1153 0 : do idg1=1,idg2
1154 0 : trace1 => esymm%Calc_irreps(idg1)%trace(1:esymm%nsym_gk)
1155 0 : ib1 = esymm%degs_bounds(1,idg1)
1156 0 : irr_idx1 = esymm%b2irrep(ib1)
1157 0 : if (irr_idx1 == 0) CYCLE
1158 0 : ctest=DOT_PRODUCT(trace1,trace2)/esymm%nsym_gk
1159 0 : if (irr_idx1==irr_idx2) ctest=ctest-one
1160 0 : max_err = MAX(max_err,ABS(ctest))
1161 0 : if (.FALSE..and.ABS(ctest)>tol3) then
1162 : write(msg,'(a,4i3,2es16.8)')&
1163 : ' WARNING: should be delta_ij: cx1 cx2, irr1, irr2, ctest: ',idg1,idg2,irr_idx1,irr_idx2,ctest
1164 : call wrtout(std_out,msg)
1165 : end if
1166 : end do
1167 : end do
1168 :
1169 0 : if (max_err>TOL_ORTHO) then
1170 0 : write(msg,'(a,es10.2)')" Too large maximum error on \sum_R \chi^*_a(R)\chi_b(R) = N_R \delta_{ab}: ",max_err
1171 0 : ABI_WARNING(msg)
1172 0 : esymm%err_status = ESYM_ORTHO_ERROR
1173 0 : esymm%err_msg = msg
1174 : else
1175 0 : write(msg,'(a,es10.2)')" maximum error on \sum_R \chi^*_a(R)\chi_b(R) = N_R \delta_{ab}: ",max_err
1176 0 : call wrtout(std_out,msg)
1177 : end if
1178 :
1179 0 : if (.not.esymm%only_trace) then
1180 : !call wrtout(std_out," **** Testing the unitary of the calculated irreps ****")
1181 0 : max_err=zero
1182 0 : do idg1=1,esymm%ndegs
1183 0 : ib1 = esymm%degs_bounds(1,idg1)
1184 0 : irr_idx1 = esymm%b2irrep(ib1)
1185 0 : if (irr_idx1 == 0) CYCLE
1186 :
1187 0 : do isym=1,esymm%nsym_gk
1188 0 : calc_mat => esymm%Calc_irreps(idg1)%mat(:,:,isym)
1189 0 : dim_mat = esymm%Calc_irreps(idg1)%dim
1190 0 : ABI_MALLOC(cidentity,(dim_mat,dim_mat))
1191 0 : call set2unit(cidentity)
1192 0 : uerr = MAXVAL( ABS(MATMUL(calc_mat,TRANSPOSE(DCONJG(calc_mat))) - cidentity) )
1193 0 : max_err = MAX(max_err,uerr)
1194 0 : ABI_FREE(cidentity)
1195 0 : if (.FALSE..and.prtvol>=10) then
1196 : write(std_out,'(a,i3,a,i2,a,es16.8,a)')&
1197 : " === idg: ",idg1,", isym: ",isym,", Error on U^* U = 1: ",uerr," ==="
1198 : call print_arr([std_out], calc_mat,dim_mat,dim_mat)
1199 : end if
1200 : end do
1201 : end do
1202 :
1203 0 : if (max_err>TOL_UNITARY) then
1204 0 : write(msg,'(a,es10.2)')" Too large maximum error on the unitary of representions matrices: ",max_err
1205 0 : ABI_WARNING(msg)
1206 0 : esymm%err_msg = msg
1207 0 : esymm%err_status = ESYM_UNITARY_ERROR
1208 : else
1209 0 : write(msg,'(a,es10.2)')" maximum error on the unitary of representions matrices: ",max_err
1210 0 : call wrtout(std_out,msg)
1211 : end if
1212 : end if
1213 : end if
1214 :
1215 0 : end subroutine esymm_finalize
1216 : !!***
1217 :
1218 : !----------------------------------------------------------------------
1219 :
1220 : !!****f* m_esymm/which_irrep
1221 : !! NAME
1222 : !! m_esymm
1223 : !!
1224 : !! FUNCTION
1225 : !! Return the index of the irreducible representation with character charact. 0 if not found.
1226 : !!
1227 : !! INPUTS
1228 : !! esymm<esymm_t>
1229 : !! trace(%nsym_gk)=The trace of the representation to be compared with the internal database (if present).
1230 : !! tolerr=Absolute error on the character.
1231 : !!
1232 : !! SOURCE
1233 :
1234 0 : pure integer function which_irrep(esymm, trace, tolerr)
1235 :
1236 : !Arguments ------------------------------------
1237 : !scalars
1238 : class(esymm_t),intent(in) :: esymm
1239 : real(dp),intent(in) :: tolerr
1240 : !arrays
1241 : complex(dp),intent(in) :: trace(esymm%nsym_gk)
1242 :
1243 : !Local variables-------------------------------
1244 : integer :: irp
1245 : ! *********************************************************************
1246 :
1247 0 : which_irrep = 0
1248 0 : if (esymm%has_chtabs) then ! Symmetry analysis can be performed.
1249 0 : do irp=1,esymm%nclass
1250 0 : if (ALL(ABS(esymm%Ref_irreps(irp)%trace(:) - trace(:)) < tolerr)) then
1251 : which_irrep = irp; exit
1252 : end if
1253 : end do
1254 : end if
1255 :
1256 0 : end function which_irrep
1257 : !!***
1258 :
1259 : !----------------------------------------------------------------------
1260 :
1261 : !!****f* m_esymm/esymm_symmetrize_mels
1262 : !! NAME
1263 : !! esymm_symmetrize_mels
1264 : !!
1265 : !! FUNCTION
1266 : !!
1267 : !! INPUTS
1268 : !!
1269 : !! SOURCE
1270 :
1271 0 : subroutine esymm_symmetrize_mels(esymm, lbnd, ubnd, in_me, out_me)
1272 :
1273 : !Arguments ------------------------------------
1274 : !scalars
1275 : class(esymm_t),target,intent(in) :: esymm
1276 : integer :: lbnd,ubnd
1277 : !arrays
1278 : complex(dp),intent(in) :: in_me(2,lbnd:ubnd,lbnd:ubnd)
1279 : complex(dp),intent(out) :: out_me(lbnd:ubnd,lbnd:ubnd)
1280 :
1281 : !Local variables-------------------------------
1282 : !scalars
1283 : integer :: idg1,b1_start,b1_stop,irp1, idg2,b2_start,b2_stop,irp2
1284 : integer :: ii,jj,ib,jb,kk,kb,lb,ll
1285 : complex(dp) :: tr_ofd,ofd,dsd,tr_dsd
1286 : type(irrep_t),pointer :: Irrep1, Irrep2, tr_Irrep1, tr_Irrep2
1287 : ! *********************************************************************
1288 :
1289 0 : if (esymm_failed(esymm)) then
1290 0 : ABI_ERROR("Symmetrization cannot be performed. You should not be here!")
1291 : end if
1292 :
1293 0 : do idg1=1,esymm%ndegs ! First loop over set of degenerate states.
1294 0 : b1_start = esymm%degs_bounds(1,idg1)
1295 0 : b1_stop = esymm%degs_bounds(2,idg1)
1296 :
1297 : !if (b1_stop<lbnd .or. b2_start >ubnd) then
1298 : ! ABI_ERROR("Wrong band indices, check esymm initialization")
1299 : !end if
1300 :
1301 0 : Irrep1 => esymm%Calc_irreps(idg1)
1302 0 : if (esymm%can_use_tr) tr_Irrep1 => esymm%trCalc_irreps(idg1)
1303 0 : irp1 = esymm%b2irrep(b1_start)
1304 :
1305 0 : do idg2=1,esymm%ndegs ! Second loop over set of degenerate states.
1306 : !write(std_out,*)" ==> Symmetrizing degenerate set ",idg1,idg2
1307 0 : b2_start = esymm%degs_bounds(1,idg2)
1308 0 : b2_stop = esymm%degs_bounds(2,idg2)
1309 0 : irp2 = esymm%b2irrep(b2_start)
1310 :
1311 0 : if (irp1/=irp2 .or. idg1==idg2) CYCLE ! Skip diago elements or elements belonging to different irreps.
1312 :
1313 0 : Irrep2 => esymm%Calc_irreps(idg2)
1314 0 : if (esymm%can_use_tr) tr_Irrep2 => esymm%trCalc_irreps(idg2)
1315 : !
1316 : ! Symmetrize the off-diagonal matrix elements.
1317 : ! summing over kk and ll. ii and jj are the indices of the bands that are symmetrized
1318 0 : do ii=1,b1_stop-b1_start+1
1319 0 : ib= ii+b1_start-1
1320 0 : do jj=1,b2_stop-b2_start+1
1321 0 : jb= jj+b2_start-1
1322 : !write(std_out,*)" ====> Symmetrizing ",ib,jb
1323 :
1324 0 : ofd= czero; tr_ofd=czero
1325 0 : do kk=1,b1_stop-b1_start+1
1326 0 : kb= kk+b1_start-1
1327 0 : do ll=1,b2_stop-b2_start+1
1328 0 : lb= ll+b2_start-1
1329 0 : dsd = sum_irreps(Irrep1,Irrep2,kk,ii,ll,jj)
1330 0 : ofd = ofd + dsd * in_me(1,kb,lb)
1331 0 : if (esymm%can_use_tr) then
1332 0 : tr_dsd = sum_irreps(tr_Irrep1,tr_Irrep2,kk,jj,ll,ii) ! Exchange of band indices.
1333 0 : tr_ofd = tr_ofd + tr_dsd * in_me(2,kb,lb) ! Contribution obtained from TR.
1334 : end if
1335 : end do
1336 : end do
1337 :
1338 0 : out_me(ib,jb)= ofd/esymm%nsym_gk
1339 0 : if (esymm%can_use_tr .and. esymm%nsym_trgk>0) out_me(ib,jb)= out_me(ib,jb) + tr_ofd/esymm%nsym_trgk
1340 : end do
1341 : end do
1342 : end do
1343 : end do
1344 :
1345 0 : end subroutine esymm_symmetrize_mels
1346 : !!***
1347 :
1348 : !----------------------------------------------------------------------
1349 :
1350 : !!****f* m_esymm/esymm_failed
1351 : !! NAME
1352 : !! esymm_failed
1353 : !!
1354 : !! FUNCTION
1355 : !!
1356 : !! SOURCE
1357 :
1358 0 : pure logical function esymm_failed(esymm)
1359 :
1360 : !Arguments ------------------------------------
1361 : class(esymm_t),intent(in) :: esymm
1362 : ! *********************************************************************
1363 :
1364 0 : esymm_failed = (esymm%err_status /= ESYM_NOERROR)
1365 :
1366 0 : end function esymm_failed
1367 : !!***
1368 :
1369 : !----------------------------------------------------------------------
1370 :
1371 : !!****f* m_esymm/polish_irreps
1372 : !! NAME
1373 : !! polish_irreps
1374 : !!
1375 : !! FUNCTION
1376 : !!
1377 : !! INPUTS
1378 : !!
1379 : !! SOURCE
1380 :
1381 0 : subroutine polish_irreps(Irreps)
1382 :
1383 : !Arguments ------------------------------------
1384 : type(irrep_t),intent(inout) :: Irreps(:)
1385 :
1386 : !Local variables-------------------------------
1387 : !scalars
1388 : integer,parameter :: ldvl1=1, ldvr1=1
1389 : integer :: irp,sym,dim,ldvr,ii,ivec,jvec,info
1390 : !character(len=500) :: msg
1391 : !arrays
1392 0 : complex(dp),allocatable :: vl(:,:),vr(:,:),vrm1(:,:),overlap(:,:), cmat(:,:),eigval(:)
1393 : ! *********************************************************************
1394 :
1395 : ! Eigen decomposition: A = V D V^{-1}.
1396 0 : do irp=1,SIZE(Irreps)
1397 0 : dim = Irreps(irp)%dim
1398 0 : ABI_MALLOC(cmat,(dim,dim))
1399 0 : ABI_MALLOC(eigval,(dim))
1400 0 : ldvr=dim
1401 0 : ABI_MALLOC(vl,(ldvl1,dim))
1402 0 : ABI_MALLOC(vr,(ldvr,dim))
1403 0 : ABI_MALLOC(vrm1,(dim,dim))
1404 0 : ABI_MALLOC(overlap,(dim,dim))
1405 0 : do sym=1,Irreps(irp)%nsym
1406 0 : cmat = Irreps(irp)%mat(:,:,sym)
1407 0 : call xgeev("No vectors","Vectors",dim,cmat,dim,eigval,vl,ldvl1,vr,ldvr)
1408 : ! Orthogonalize the eigenvectors using Cholesky orthogonalization.
1409 0 : do jvec=1,dim
1410 0 : do ivec=1,jvec
1411 0 : overlap(ivec,jvec) = DOT_PRODUCT(vr(:,ivec),vr(:,jvec))
1412 : end do
1413 : end do
1414 : ! 2) Cholesky factorization: overlap = U^H U with U upper triangle matrix.
1415 0 : call ZPOTRF('U',dim,overlap,dim,info)
1416 0 : ABI_CHECK(info == 0, sjoin('ZPOTRF returned info=', itoa(info)))
1417 :
1418 : ! 3) Solve X U = Vr, on exit the Vr treated by this node is orthonormalized.
1419 0 : call ZTRSM('R','U','N','N',dim,dim,cone,overlap,dim,vr,dim)
1420 : !write(std_out,*)"After ortho",MATMUL(TRANSPOSE(CONJG(vr)),vr)
1421 :
1422 0 : vrm1 = vr
1423 0 : call xginv(vrm1,dim)
1424 0 : do ii=1,dim
1425 0 : eigval(ii) = eigval(ii)/ABS(eigval(ii)) ! Rescale the eigevalues.
1426 0 : vrm1(ii,:) = eigval(ii) * vrm1(ii,:)
1427 : end do
1428 0 : Irreps(irp)%mat(:,:,sym) = MATMUL(vr,vrm1)
1429 0 : Irreps(irp)%trace(sym) = get_trace(Irreps(irp)%mat(:,:,sym))
1430 : end do
1431 0 : ABI_FREE(cmat)
1432 0 : ABI_FREE(eigval)
1433 0 : ABI_FREE(vl)
1434 0 : ABI_FREE(vr)
1435 0 : ABI_FREE(vrm1)
1436 0 : ABI_FREE(overlap)
1437 : end do
1438 :
1439 0 : end subroutine polish_irreps
1440 : !!***
1441 :
1442 : !----------------------------------------------------------------------
1443 :
1444 0 : end module m_esymm
|