Line data Source code
1 : !--------------------------------------------------------------------------------
2 : ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
3 : ! This file is part of FLEUR and available as free software under the conditions
4 : ! of the MIT license as expressed in the LICENSE file in more detail.
5 : !--------------------------------------------------------------------------------
6 :
7 : MODULE m_types_dmi
8 : USE m_types
9 : USE m_types_forcetheo
10 : USE m_judft
11 : IMPLICIT NONE
12 : PRIVATE
13 : TYPE,EXTENDS(t_forcetheo) :: t_forcetheo_dmi
14 : INTEGER :: q_done
15 : REAL,ALLOCATABLE:: qvec(:,:)
16 : REAL,ALLOCATABLE:: theta(:)
17 : REAL,ALLOCATABLE:: phi(:)
18 : real,ALLOCATABLE:: ef(:) !shifts of fermi energy
19 : REAL,ALLOCATABLE:: evsum(:,:,:)
20 : REAL,ALLOCATABLE:: h_so(:,:,:,:)
21 : CONTAINS
22 : PROCEDURE :: start =>dmi_start
23 : PROCEDURE :: next_job=>dmi_next_job
24 : PROCEDURE :: eval =>dmi_eval
25 : PROCEDURE :: postprocess => dmi_postprocess
26 : PROCEDURE :: init => dmi_init !not overloaded
27 : PROCEDURE :: dist => dmi_dist !not overloaded
28 : END TYPE t_forcetheo_dmi
29 : PUBLIC t_forcetheo_dmi
30 : CONTAINS
31 :
32 :
33 0 : SUBROUTINE dmi_init(this,q,theta,phi,ef_shifts,ntype)
34 : USE m_calculator
35 : USE m_constants
36 : IMPLICIT NONE
37 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
38 : REAL,INTENT(in) :: q(:,:)
39 : REAL,INTENT(IN) :: theta(:),phi(:),ef_shifts(:)
40 : INTEGER,INTENT(IN) :: ntype
41 0 : this%l_needs_vectors=.true.
42 0 : this%theta=theta
43 0 : this%phi=phi
44 0 : this%ef=ef_shifts
45 :
46 0 : IF (SIZE(this%phi).NE.SIZE(this%theta)) CALL &
47 0 : judft_error("Lists for theta/phi must have the same length in DMI force theorem calculations")
48 :
49 : ! use same definition of rotation angles as in noco-routines
50 0 : this%theta=-this%theta
51 0 : this%phi=this%phi+pi_const
52 :
53 :
54 0 : ALLOCATE(this%qvec(3,SIZE(q,2)))
55 0 : this%qvec=q
56 :
57 0 : ALLOCATE(this%evsum(size(this%ef),0:SIZE(this%phi),SIZE(q,2)))
58 0 : ALLOCATE(this%h_so(0:ntype,size(this%ef),SIZE(this%phi),SIZE(q,2)))
59 :
60 0 : this%evsum=0;this%h_so=0.0
61 0 : END SUBROUTINE dmi_init
62 :
63 0 : SUBROUTINE dmi_start(this,potden,l_io)
64 : USE m_types_potden
65 : IMPLICIT NONE
66 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
67 : TYPE(t_potden) ,INTENT(INOUT) :: potden
68 : LOGICAL,INTENT(IN) :: l_io
69 0 : this%q_done=0
70 0 : CALL this%t_forcetheo%start(potden,l_io) !call routine of basis type
71 0 : END SUBROUTINE dmi_start
72 :
73 0 : LOGICAL FUNCTION dmi_next_job(this,fmpi,lastiter,atoms,noco,nococonv)
74 : USE m_types_setup
75 : USE m_xmlOutput
76 : USE m_constants
77 : USE m_types_nococonv
78 : USE m_types_mpi
79 : IMPLICIT NONE
80 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
81 : TYPE(t_mpi), INTENT(IN) :: fmpi
82 : LOGICAL,INTENT(IN) :: lastiter
83 : TYPE(t_atoms),INTENT(IN) :: atoms
84 : !Stuff that might be modified...
85 : TYPE(t_noco),INTENT(IN) :: noco
86 : TYPE(t_nococonv),INTENT(INOUT) :: nococonv
87 : INTEGER :: itype
88 : CHARACTER(LEN=12):: attributes(2)
89 0 : IF (.NOT.lastiter) THEN
90 0 : dmi_next_job=this%t_forcetheo%next_job(fmpi,lastiter,atoms,noco,nococonv)
91 0 : RETURN
92 : ENDIF
93 : !OK, now we start the DMI-loop
94 0 : this%l_in_forcetheo_loop = .true.
95 0 : this%q_done=this%q_done+1
96 0 : dmi_next_job=(this%q_done<=SIZE(this%qvec,2)) !still q-vectors to do
97 0 : IF (.NOT.dmi_next_job) RETURN
98 :
99 : !Now modify the noco-file
100 0 : nococonv%qss=this%qvec(:,this%q_done)
101 0 : if (.not.noco%l_spav) call judft_warn("l_spav=T should be set in DMI force theorem mode")
102 : !Modify the alpha-angles
103 0 : DO iType = 1,atoms%ntype
104 0 : nococonv%alph(iType) = noco%alph_inp(iType) + tpi_const*dot_PRODUCT(nococonv%qss,atoms%taual(:,atoms%firstAtom(itype)))
105 : END DO
106 0 : IF (.NOT.this%l_io) RETURN
107 :
108 0 : IF (fmpi%irank .EQ. 0) THEN
109 0 : IF (this%q_done.NE.1) CALL closeXMLElement('Forcetheorem_Loop')
110 0 : WRITE(attributes(1),'(a)') 'DMI'
111 0 : WRITE(attributes(2),'(i5)') this%q_done
112 0 : CALL openXMLElementPoly('Forcetheorem_Loop',(/'calculationType','No '/),attributes)
113 : END IF
114 : END FUNCTION dmi_next_job
115 :
116 0 : SUBROUTINE dmi_postprocess(this)
117 : USE m_xmlOutput
118 : #ifdef CPP_MPI
119 : USE mpi
120 : #endif
121 : IMPLICIT NONE
122 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
123 :
124 : !Locals
125 : INTEGER:: n,q,i,nef,ierr
126 : CHARACTER(LEN=20):: attributes(6)
127 : CHARACTER(LEN=16) :: atom_name
128 0 : IF (this%q_done==0) RETURN
129 0 : IF (this%l_io) THEN
130 : !Now output the results
131 0 : CALL closeXMLElement('Forcetheorem_Loop')
132 0 : attributes = ''
133 0 : WRITE(attributes(2),'(i5)') SIZE(this%evsum,1)
134 0 : WRITE(attributes(3),'(i5)') SIZE(this%evsum,2)-1
135 0 : WRITE(attributes(1),'(i5)') SIZE(this%evsum,3)
136 0 : WRITE(attributes(4),'(a)') 'Htr'
137 0 : CALL openXMLElement('Forcetheorem_DMI',(/'qPoints','ef ','Angles ','units '/),attributes(:4))
138 0 : DO q=1,SIZE(this%evsum,3)
139 0 : WRITE(attributes(2),'(i5)') q
140 0 : DO nef=1,size(this%ef,1)
141 0 : WRITE(attributes(3),'(f10.5)') this%ef(nef)
142 0 : WRITE(attributes(4),'(f15.8)') this%evsum(nef,0,q)
143 0 : CALL writeXMLElementForm('Entry',(/'q ','ef-shift','ev-sum '/),attributes(2:4),RESHAPE((/1,8,6,5,12,12/),(/3,2/)))
144 0 : DO n=1,SIZE(this%evsum,2)-1
145 0 : WRITE(attributes(4),'(f15.8)') this%theta(n)
146 0 : WRITE(attributes(5),'(f15.8)') this%phi(n)
147 0 : WRITE(attributes(6),'(f15.8)') this%evsum(nef,n,q)
148 0 : CALL writeXMLElementForm('Entry',(/'q ','ef-shift','theta ','phi ','ev-sum '/),attributes(2:6),RESHAPE((/1,8,5,3,6,5,20,20,20,20/),(/5,2/)))
149 0 : write(attributes(6),'(f15.8)') this%h_so(0,nef,n,q)
150 0 : CALL writeXMLElementForm('allAtoms',(/'q ','ef-shift','theta ','phi ','H_so '/),attributes(2:6),RESHAPE((/1,8,5,3,6,5,20,20,20,20/),(/5,2/)))
151 0 : DO i=1,size(this%h_so,1)-1
152 0 : write(attributes(6),'(f15.8)') this%h_so(i,nef,n,q)
153 0 : write(attributes(1),'(i0)') i
154 0 : CALL writeXMLElementForm('singleAtom',(/'atomType','q ','ef-shift','theta ','phi ','H_so '/),attributes,RESHAPE((/8,8,1,5,3,6,5,5,20,20,20,20/),(/6,2/)))
155 : END DO
156 : END DO
157 : END DO
158 : END DO
159 0 : CALL closeXMLElement('Forcetheorem_DMI')
160 : ENDIF
161 :
162 : #ifdef CPP_MPI
163 0 : CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! This barrier is placed to ensure that the output above this line is actually written out.
164 : #endif
165 :
166 0 : CALL judft_end("Forcetheorem DMI")
167 : END SUBROUTINE dmi_postprocess
168 :
169 0 : SUBROUTINE dmi_dist(this,fmpi)
170 : #ifdef CPP_MPI
171 : USE mpi
172 : USE m_mpi_bc_tool
173 : #endif
174 : USE m_types_mpi
175 : IMPLICIT NONE
176 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
177 : TYPE(t_mpi),INTENT(in):: fmpi
178 :
179 : INTEGER:: i,q,ierr,n
180 : #ifdef CPP_MPI
181 0 : CALL mpi_bc(this%theta,0,fmpi%mpi_comm)
182 0 : CALL mpi_bc(this%phi,0,fmpi%mpi_comm)
183 0 : CALL mpi_bc(this%qvec,0,fmpi%mpi_comm)
184 0 : CALL mpi_bc(this%ef,0,fmpi%mpi_comm)
185 : #endif
186 0 : END SUBROUTINE dmi_dist
187 :
188 0 : FUNCTION dmi_eval(this,eig_id,atoms,kpts,sym,&
189 : cell,noco,nococonv, input,fmpi, enpara,v,results)RESULT(skip)
190 : USE m_types
191 : USE m_ssomat
192 : IMPLICIT NONE
193 : CLASS(t_forcetheo_dmi),INTENT(INOUT):: this
194 : LOGICAL :: skip
195 : !Stuff that might be used...
196 : TYPE(t_mpi),INTENT(IN) :: fmpi
197 :
198 :
199 : TYPE(t_input),INTENT(IN) :: input
200 : TYPE(t_noco),INTENT(IN) :: noco
201 : TYPE(t_nococonv),INTENT(IN) :: nococonv
202 : TYPE(t_sym),INTENT(IN) :: sym
203 : TYPE(t_cell),INTENT(IN) :: cell
204 : TYPE(t_kpts),INTENT(IN) :: kpts
205 : TYPE(t_atoms),INTENT(IN) :: atoms
206 : TYPE(t_enpara),INTENT(IN) :: enpara
207 : TYPE(t_potden),INTENT(IN) :: v
208 : TYPE(t_results),INTENT(IN) :: results
209 : INTEGER,INTENT(IN) :: eig_id
210 0 : skip=.FALSE.
211 0 : IF (this%q_done==0) RETURN
212 :
213 : CALL ssomat(this%evsum(:,:,this%q_done),this%h_so(:,:,:,this%q_done),this%theta,this%phi,eig_id,atoms,kpts,sym,&
214 0 : cell,noco,nococonv, input,fmpi, enpara,v,results,this%ef+results%ef)
215 0 : skip=.TRUE.
216 :
217 0 : END FUNCTION dmi_eval
218 :
219 :
220 0 : END MODULE m_types_dmi
|