Merge lp:~nickpapior/siesta/4.1-ts into lp:siesta/4.1

Proposed by Nick Papior
Status: Merged
Approved by: Nick Papior
Approved revision: 913
Merged at revision: 904
Proposed branch: lp:~nickpapior/siesta/4.1-ts
Merge into: lp:siesta/4.1
Diff against target: 3867 lines (+1635/-665)
25 files modified
Docs/tbtrans.tex (+98/-14)
Src/Makefile (+7/-6)
Src/class_TriMat.T90 (+1/-1)
Src/m_pivot.F90 (+14/-4)
Src/m_pivot_methods.F90 (+380/-107)
Src/m_ts_cctype.f90 (+12/-2)
Src/m_ts_contour_eq.f90 (+144/-21)
Src/m_ts_contour_neq.f90 (+127/-12)
Src/m_ts_io_ctype.f90 (+93/-23)
Src/m_ts_method.f90 (+4/-0)
Src/m_ts_options.F90 (+17/-17)
Src/m_ts_pivot.F90 (+31/-8)
Src/m_ts_tri_init.F90 (+63/-0)
Util/SpPivot/pvtsp.F90 (+23/-15)
Util/TS/TBtrans/Makefile (+29/-27)
Util/TS/TBtrans/m_tbt_contour.F90 (+122/-9)
Util/TS/TBtrans/m_tbt_options.F90 (+27/-3)
Util/TS/TBtrans/m_tbt_proj.F90 (+9/-3)
Util/TS/TBtrans/m_tbt_regions.F90 (+15/-2)
Util/TS/TBtrans/m_tbt_save.F90 (+35/-9)
Util/TS/TBtrans/m_tbt_sigma_save.F90 (+10/-3)
Util/TS/TBtrans/m_tbt_tri_scat.F90 (+277/-316)
Util/TS/TBtrans/m_tbt_trik.F90 (+93/-58)
Util/TS/TBtrans/m_tbtrans.F90 (+3/-3)
version.info (+1/-2)
To merge this branch: bzr merge lp:~nickpapior/siesta/4.1-ts
Reviewer Review Type Date Requested Status
Nick Papior Approve
Review via email: mp+345112@code.launchpad.net

Commit message

Enabled DM calculation for TBtrans. Also speeded up some of the Green function calculations in TBtrans.

Secondly, some bugs related to the pivoting schemes has been fixed. These fixes are for systems
where there is a gap between electrodes.

Lastly, user-defined energy points are now a reality in tbtrans.

To post a comment you must log in.
Revision history for this message
Nick Papior (nickpapior) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Docs/tbtrans.tex'
2--- Docs/tbtrans.tex 2018-04-06 19:25:57 +0000
3+++ Docs/tbtrans.tex 2018-05-04 19:08:45 +0000
4@@ -124,7 +124,13 @@
5 \item Projected transmission of eigenstates
6
7 \item Orbital resolved ``bond-currents'' which may subsequently be
8- analyzed to yield actual bond-currents.
9+ analyzed to yield actual bond-currents
10+
11+ \item Density matrices using the Green function and/or the
12+ spectral density
13+
14+ \item COOP and COHP curves using the Green function and/or the
15+ spectral density.
16
17 \end{itemize}
18
19@@ -800,7 +806,30 @@
20 \end{equation}
21 where the sum is over all electrodes, $\mathbf G$ and $\mathbf A$ are
22 the Green and spectral function, respectively. Note that typically
23-$\rho_{\mathrm{bound-states}}=0$.
24+$\rho_{\mathrm{bound-states}}=0$.
25+
26+The below two options enables the calculation of the energy resolved
27+density matrices. In effect they may be used to construct
28+$\mathrm{LDOS}(E)$ profiles using \sisl.
29+
30+\begin{fdflogicalF}{TBT.DM!Gf}
31+ \fdfdepend{TBT.Atoms!Device}
32+
33+ Calculate the energy and $k$-resolved density matrix for the Green
34+ function. The density matrix may be used to construct
35+ real-space LDOS profiles.
36+
37+\end{fdflogicalF}
38+
39+\begin{fdflogicalF}{TBT.DM!A}
40+ \fdfdepend{TBT.Atoms!Device}
41+
42+ Calculate the energy and $k$-resolved density matrix for the
43+ electrode spectral functions. The density matrix may be used to
44+ construct real-space LDOS profiles.
45+
46+\end{fdflogicalF}
47+
48
49 In addition to the DOS analysis of the Green and spectral functions,
50 the Crystal Orbital Overlap Population and Crystal Orbital Hamilton
51@@ -1326,9 +1355,10 @@
52 Thus \emph{a} and \emph{b} are energies.
53
54
55- \option[points/delta]%
56+ \option[points|delta|file]%
57 \fdfindex{TBT.Contour!<>!points}%
58 \fdfindex{TBT.Contour!<>!delta}%
59+ \fdfindex{TBT.Contour!<>!file}%
60
61 Define the number of integration points/energy separation.
62 If specifying the number of points an integer should be supplied.
63@@ -1336,6 +1366,31 @@
64 If specifying the separation between consecutive points an energy
65 should be supplied (e.g. \fdf*{0.01 eV}).
66
67+ Optionally one may specify a file which contains the energy points
68+ and their weights.
69+
70+ This file has the same formatting as the \sysfile{TBT.CC} output
71+ with some optional inputs. Below is an example input file.
72+ \begin{shellexample}
73+# There are 2 different input options:
74+# 1. Re[E] Im[E] W (optional unit)
75+# 2. Re[E] W (optional unit) (imaginary part will be device Eta)
76+# If the unit is specified on any line, all subsequent lines will use
77+# the specified unit. Default unit is eV!
78+# Empty lines and lines starting with # will be ignored.
79+-0.5 0.1 # E = -0.5 eV, weight (for integrating current) of 0.1 eV
80+-0.01 0.1 Ry # E = -0.01 Ry and weight 0.1 Ry
81+-0.02 0.1 # E = -0.02 Ry (above unit continue) and weight 0.1 Ry
82+-0.2 0.1 eV # E = -0.2 eV and weight 0.1 eV
83+-0.2 1. 0.1 # E = -0.2 eV and 1. eV eta and weight 0.1 eV
84+\end{shellexample}
85+
86+ If the file specified is \sysfile{TBT.CC} the same energy points
87+ will be used. Note that the resulting \sysfile{TBT.nc} file does
88+ not store the energies as complex numbers, thus one cannot
89+ subsequently extract the $\eta$ value used for the individual
90+ energy points.
91+
92 \option[method]%
93 \fdfindex{TBT.Contour!<>!method}%
94
95@@ -1360,6 +1415,9 @@
96
97 \note has \fdf*{opt precision <>}.
98
99+ \option[user]%
100+ User defined input via a file.
101+
102 \end{fdfoptions}
103
104 \option[opt]%
105@@ -1377,14 +1435,28 @@
106 TBT.Contours.Eta 0. eV
107 %block TBT.Contours
108 line
109- %endblock TBT.Contours
110+ %endblock
111 %block TBT.Contour.line
112 from -2. eV to 2. eV
113 delta 0.01 eV
114 method mid-rule
115- %endblock TBT.Contour.line
116+ %endblock
117 \end{fdfexample}
118
119+An example of input using a file (note that regular contour setups may
120+be used together with file-inputs)
121+\begin{fdfexample}
122+ TBT.Contours.Eta 0. eV
123+ %block TBT.Contours
124+ file
125+ %endblock
126+ %block TBT.Contour.file
127+ from 2. eV to 2.5 eV
128+ file my_energies
129+ %endblock
130+\end{fdfexample}
131+Note that the energy specifications are necessary (due to internal
132+bookkeeping).
133
134 \subsection{Chemical potentials}
135
136@@ -1934,23 +2006,17 @@
137
138 Specify the precision used for storing DOS in NetCDF4.
139
140- See \fdf{TBT.CDF!Precision}.
141-
142 \end{fdfentry}
143
144 \begin{fdfentry}{TBT.CDF!T.Precision}[string]<{<\fdf{TBT.CDF!Precision}>}>
145
146 Specify the precision used for storing transmission function in NetCDF4.
147
148- See \fdf{TBT.CDF!Precision}.
149-
150 \end{fdfentry}
151
152 \begin{fdfentry}{TBT.CDF!T.Eig.Precision}[string]<{<\fdf{TBT.CDF!Precision}>}>
153
154 Specify the precision used for storing transmission eigenvalues in NetCDF4.
155-
156- See \fdf{TBT.CDF!Precision}.
157
158 \end{fdfentry}
159
160@@ -1958,7 +2024,23 @@
161
162 Specify the precision used for storing orbital current in NetCDF4.
163
164- See \fdf{TBT.CDF!Precision}.
165+ \note This is heavily advised to be in single precision as this may
166+ easily use large amounts of disk-space if in double precision.
167+
168+\end{fdfentry}
169+
170+\begin{fdfentry}{TBT.CDF!DM.Precision}[string]<{<\fdf{TBT.CDF!Precision}>}>
171+
172+ Specify the precision used for storing density matrices in NetCDF4.
173+
174+ \note This is heavily advised to be in single precision as this may
175+ easily use large amounts of disk-space if in double precision.
176+
177+\end{fdfentry}
178+
179+\begin{fdfentry}{TBT.CDF!COOP.Precision}[string]<{<\fdf{TBT.CDF!Precision}>}>
180+
181+ Specify the precision used for storing COOP and COHP curves in NetCDF4.
182
183 \note This is heavily advised to be in single precision as this may
184 easily use large amounts of disk-space if in double precision.
185@@ -1978,7 +2060,9 @@
186 NetCDF4 file using:
187 \begin{shellexample}
188 nccopy -d 3 siesta.TBT.nc newsiesta.TBT.nc
189-\end{shellexample}
190+ \end{shellexample}
191+
192+ \note one \emph{can not} do parallel I/O together with compression.
193
194 \end{fdfentry}
195
196@@ -1988,7 +2072,7 @@
197 MPI processors this may increase performance.
198
199 \note this automatically sets the compression to 0 (one cannot
200- compress and perform parallel IO)
201+ compress and perform parallel IO).
202
203 \end{fdflogicalF}
204
205
206=== modified file 'Src/Makefile'
207--- Src/Makefile 2018-04-24 09:14:21 +0000
208+++ Src/Makefile 2018-05-04 19:08:45 +0000
209@@ -944,13 +944,14 @@
210 m_ts_contour_eq.o: m_gauss_fermi_17.o m_gauss_fermi_18.o m_gauss_fermi_19.o
211 m_ts_contour_eq.o: m_gauss_fermi_20.o m_gauss_fermi_22.o m_gauss_fermi_24.o
212 m_ts_contour_eq.o: m_gauss_fermi_26.o m_gauss_fermi_28.o m_gauss_fermi_30.o
213-m_ts_contour_eq.o: m_gauss_fermi_inf.o m_gauss_quad.o m_integrate.o m_ts_aux.o
214-m_ts_contour_eq.o: m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
215+m_ts_contour_eq.o: m_gauss_fermi_inf.o m_gauss_quad.o m_integrate.o m_io.o
216+m_ts_contour_eq.o: m_ts_aux.o m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
217 m_ts_contour_eq.o: m_ts_io_contour.o m_ts_io_ctype.o parallel.o precision.o
218 m_ts_contour_eq.o: units.o
219-m_ts_contour_neq.o: m_gauss_quad.o m_integrate.o m_ts_aux.o m_ts_cctype.o
220-m_ts_contour_neq.o: m_ts_chem_pot.o m_ts_electype.o m_ts_io_contour.o
221-m_ts_contour_neq.o: m_ts_io_ctype.o parallel.o precision.o units.o
222+m_ts_contour_neq.o: m_gauss_quad.o m_integrate.o m_io.o m_ts_aux.o
223+m_ts_contour_neq.o: m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
224+m_ts_contour_neq.o: m_ts_io_contour.o m_ts_io_ctype.o parallel.o precision.o
225+m_ts_contour_neq.o: units.o
226 m_ts_debug.o: class_Sparsity.o class_TriMat.o geom_helper.o parallel.o
227 m_ts_debug.o: precision.o
228 m_ts_dm_update.o: class_OrbitalDistribution.o class_SpData1D.o class_SpData2D.o
229@@ -993,7 +994,7 @@
230 m_ts_io.o: class_SpData2D.o class_Sparsity.o geom_helper.o m_io_s.o m_ncdf_io.o
231 m_ts_io.o: m_os.o m_sparse.o parallel.o precision.o sys.o
232 m_ts_io_contour.o: precision.o units.o
233-m_ts_io_ctype.o: parallel.o precision.o units.o
234+m_ts_io_ctype.o: m_io.o parallel.o precision.o units.o
235 m_ts_iodm.o: class_OrbitalDistribution.o class_SpData2D.o class_Sparsity.o
236 m_ts_iodm.o: m_io_s.o m_os.o parallel.o precision.o
237 m_ts_kpoints.o: files.o find_kgrid.o kpoint_grid.o m_ts_global_vars.o
238
239=== modified file 'Src/class_TriMat.T90'
240--- Src/class_TriMat.T90 2018-03-26 08:06:50 +0000
241+++ Src/class_TriMat.T90 2018-05-04 19:08:45 +0000
242@@ -77,7 +77,7 @@
243 public :: NEW_TYPE, print_type, init_val
244
245 public :: val
246- public :: index, index_sub, part_index
247+ public :: index, index_sub, index_block, part_index
248 public :: cum_rows
249 public :: nrows_g
250 public :: parts, which_part
251
252=== modified file 'Src/m_pivot.F90'
253--- Src/m_pivot.F90 2017-11-13 07:41:00 +0000
254+++ Src/m_pivot.F90 2018-05-04 19:08:45 +0000
255@@ -30,10 +30,14 @@
256 integer, parameter :: PVT_PCG = 7
257 integer, parameter :: PVT_REV_PCG = 8
258 #ifdef SIESTA__METIS
259- integer, parameter :: PVT_METIS = 9
260+ integer, parameter :: PVT_METIS_NODEND = 9
261 #endif
262 integer, parameter :: PVT_CONNECT = 10
263 integer, parameter :: PVT_REV_CONNECT = 11
264+#ifdef SIESTA__METIS
265+ integer, parameter :: PVT_METIS_PARTGRAPHKWAY = 12
266+ integer, parameter :: PVT_METIS_PARTGRAPHRECURSIVE = 13
267+#endif
268
269 contains
270
271@@ -120,9 +124,15 @@
272 call rev_GGPS(n,n_nzs,ncol,l_ptr,l_col,lsub,pvt , priority = priority )
273 pvt%name = 'rev-General-Gibbs-Poole-Stockmeyer'
274 #ifdef SIESTA__METIS
275- else if ( method == PVT_METIS ) then
276- call metis_pvt(n,n_nzs,ncol,l_ptr,l_col,lsub,pvt, priority = priority)
277- pvt%name = 'metis'
278+ else if ( method == PVT_METIS_NODEND ) then
279+ call metis_NodeND_pvt(n,n_nzs,ncol,l_ptr,l_col,lsub,pvt, priority = priority)
280+ pvt%name = 'metis-NodeND'
281+ else if ( method == PVT_METIS_PARTGRAPHKWAY ) then
282+ call metis_PartGraphKway_pvt(n,n_nzs,ncol,l_ptr,l_col,lsub,pvt, priority = priority)
283+ pvt%name = 'metis-PartGraphKway'
284+ else if ( method == PVT_METIS_PARTGRAPHRECURSIVE ) then
285+ call metis_PartGraphRecursive_pvt(n,n_nzs,ncol,l_ptr,l_col,lsub,pvt, priority = priority)
286+ pvt%name = 'metis-PartGraphRecursive'
287 #endif
288 else
289 call die('m_pivot: Programming error, unknown method')
290
291=== modified file 'Src/m_pivot_methods.F90'
292--- Src/m_pivot_methods.F90 2018-04-07 19:13:42 +0000
293+++ Src/m_pivot_methods.F90 2018-05-04 19:08:45 +0000
294@@ -30,7 +30,9 @@
295 public :: rev_connectivity_graph
296
297 #ifdef SIESTA__METIS
298- public :: metis_pvt
299+ public :: metis_PartGraphKway_pvt
300+ public :: metis_PartGraphRecursive_pvt
301+ public :: metis_NodeND_pvt
302 #endif
303
304 public :: bandwidth, profile
305@@ -1446,7 +1448,87 @@
306
307
308 #ifdef SIESTA__METIS
309- subroutine metis_pvt(n,nnzs,n_col,l_ptr,l_col,sub,pvt, priority)
310+
311+ subroutine metis_adjacency_graph(n,nnzs,n_col,l_ptr,l_col,sub, &
312+ xadj, adjncy, w, priority)
313+ use iso_c_binding, only: c_int
314+ integer, intent(in) :: n, nnzs
315+ integer, intent(in) :: n_col(n), l_ptr(n), l_col(nnzs)
316+ type(tRgn), intent(in) :: sub
317+ integer(c_int), intent(inout), allocatable :: xadj(:), adjncy(:), w(:)
318+ integer, intent(in), optional :: priority(n)
319+
320+ integer :: io, i, ptr, ind, nc, j, nadj
321+
322+ ! Allocate adjacency graphs
323+ allocate(xadj(0:sub%n), w(sub%n) )
324+
325+ ! First count adjacencies
326+ xadj(0) = 0 ! + 1 : fortran-style
327+ do i = 1 , sub%n
328+
329+ io = sub%r(i)
330+ ptr = l_ptr(io)
331+ nc = n_col(io)
332+
333+ ! Count number of elements in
334+ ! the sub-space
335+ nadj = 0
336+ do ind = ptr + 1 , ptr + nc
337+ if ( in_rgn(sub,l_col(ind)) ) then
338+ ! Skip "on-site" connections
339+ if ( l_col(ind) /= io ) then
340+ nadj = nadj + 1
341+ end if
342+ end if
343+ end do
344+
345+ xadj(i) = xadj(i-1) + nadj
346+
347+ if ( present(priority) ) then
348+ w(i) = priority(io) + 1
349+ else
350+ w(i) = 1
351+ end if
352+
353+ end do
354+
355+ ! transfer to local adjacency graph
356+ allocate( adjncy(xadj(sub%n)) )
357+
358+ ! Create adjncy
359+ nadj = 0
360+ do i = 1 , sub%n
361+
362+ io = sub%r(i)
363+ ptr = l_ptr(io)
364+ nc = n_col(io)
365+
366+ ! Count number of elements in
367+ ! the sub-space
368+ do ind = ptr + 1 , ptr + nc
369+ j = rgn_pivot(sub,l_col(ind))
370+ if ( j > 0 ) then
371+ ! Skip "on-site" connections
372+ if ( l_col(ind) /= io ) then
373+ nadj = nadj + 1
374+ adjncy(nadj) = j - 1 ! + 1 : fortran style
375+ end if
376+ end if
377+ end do
378+
379+ if ( nadj /= xadj(i) ) then
380+ print *,i,nadj, xadj(i)
381+ call die('metis_adjacency_graph: Error in creating &
382+ &adjacency graph.')
383+ end if
384+
385+ end do
386+
387+ end subroutine metis_adjacency_graph
388+
389+
390+ subroutine metis_NodeND_pvt(n,nnzs,n_col,l_ptr,l_col,sub,pvt, priority)
391 use iso_c_binding, only: c_int, c_ptr, c_loc
392 integer, intent(in) :: n, nnzs
393 integer, intent(in) :: n_col(n), l_ptr(n), l_col(nnzs)
394@@ -1460,7 +1542,6 @@
395 integer(c_int), allocatable, target :: w(:)
396 integer(c_int) :: iret, nvtxs, opts(100) ! In 5.0.1 it is 40, but ...
397 type(c_ptr) :: wp
398- integer :: nadj
399
400 interface
401 integer(c_int) function METIS_SetDefaultOptions(opts) &
402@@ -1480,8 +1561,7 @@
403 end function METIS_NodeND
404 end interface
405
406- ! variables for the loop
407- integer :: io, i, ptr, ind, nc, j
408+ integer :: i
409
410 call rgn_delete(pvt)
411
412@@ -1494,7 +1574,7 @@
413 if ( iret /= 1 ) then
414 opts(6) = 256 ! increase debug level and re-run for full dbg-lvl
415 iret = METIS_setdefaultoptions(opts)
416- call die('metis_pvt: Error on initializing default options.')
417+ call die('metis_NodeND: Error on initializing default options.')
418 end if
419
420 ! set options
421@@ -1504,74 +1584,15 @@
422 opts(8) = 1 ! NCUT == Number of cuts
423 opts(10) = 1 ! NO2HOP == does not use 2 hop
424 opts(11) = 1 ! MINCONN == Explicitly minimize the maximum connectivity
425- opts(12) = 1 ! CONTIG == Forces contiguous
426+ opts(12) = 0 ! CONTIG == Forces contiguous
427 opts(13) = 1 ! COMPRESS == compress similar adjacency nodes
428 opts(16) = 1 ! NSEPS(1) == tries in the separator
429
430- ! Allocate adjacency graphs
431- allocate(xadj(0:sub%n), perm(sub%n), iperm(sub%n) , w(sub%n) )
432-
433- ! First count adjacencies
434- xadj(0) = 0 ! + 1 : fortran-style
435- do i = 1 , sub%n
436-
437- io = sub%r(i)
438- ptr = l_ptr(io)
439- nc = n_col(io)
440-
441- ! Count number of elements in
442- ! the sub-space
443- nadj = 0
444- do ind = ptr + 1 , ptr + nc
445- if ( in_rgn(sub,l_col(ind)) ) then
446- ! Skip "on-site" connections
447- if ( l_col(ind) /= io ) then
448- nadj = nadj + 1
449- end if
450- end if
451- end do
452-
453- xadj(i) = xadj(i-1) + nadj
454-
455- if ( present(priority) ) then
456- w(i) = priority(io) + 1
457- else
458- w(i) = 1
459- end if
460-
461- end do
462-
463- ! transfer to local adjacency graph
464- allocate( adjncy(xadj(sub%n)) )
465-
466- ! Create adjncy
467- nadj = 0
468- do i = 1 , sub%n
469-
470- io = sub%r(i)
471- ptr = l_ptr(io)
472- nc = n_col(io)
473-
474- ! Count number of elements in
475- ! the sub-space
476- do ind = ptr + 1 , ptr + nc
477- j = rgn_pivot(sub,l_col(ind))
478- if ( j > 0 ) then
479- ! Skip "on-site" connections
480- if ( l_col(ind) /= io ) then
481- nadj = nadj + 1
482- adjncy(nadj) = j - 1 ! + 1 : fortran style
483- end if
484- end if
485- end do
486-
487- if ( nadj /= xadj(i) ) then
488- print *,i,nadj, xadj(i)
489- call die('metis_pvt: Error in creating &
490- &adjacency graph.')
491- end if
492-
493- end do
494+ ! Setup the adjacency graph
495+ call metis_adjacency_graph(n,nnzs,n_col,l_ptr,l_col,sub, &
496+ xadj, adjncy, w, priority)
497+
498+ allocate(perm(sub%n), iperm(sub%n))
499
500 ! Call metis
501 wp = c_loc(w(1))
502@@ -1583,26 +1604,273 @@
503 opts(6) = 256
504 iret = METIS_NodeND(nvtxs, xadj, adjncy, wp, opts, perm, iperm)
505 print *,iret
506- call die('pivot_method: metis, error in pivoting.')
507+ call die('metis_NodeND: error in pivoting.')
508 end if
509
510 ! Clean-up
511- deallocate(xadj,adjncy,iperm)
512+ deallocate(xadj,adjncy,w,iperm)
513
514 call rgn_init(pvt,sub%n)
515
516-
517 ! Transfer pivoting to actual pivoting index
518 do i = 1 , sub%n
519 pvt%r(i) = sub%r(perm(i)+1) ! - 1 : fortran style
520 end do
521
522 ! Clean-up
523- deallocate(perm,w)
524-
525- if ( pvt%n /= sub%n ) call die('metis: Error in algorithm')
526-
527- end subroutine metis_pvt
528+ deallocate(perm)
529+
530+ if ( pvt%n /= sub%n ) call die('metis_NodeND: Error in algorithm')
531+
532+ end subroutine metis_NodeND_pvt
533+
534+ subroutine metis_PartGraphKway_pvt(n,nnzs,n_col,l_ptr,l_col,sub,pvt, priority)
535+ use iso_c_binding, only: c_int, c_ptr, c_loc, c_null_ptr
536+ integer, intent(in) :: n, nnzs
537+ integer, intent(in) :: n_col(n), l_ptr(n), l_col(nnzs)
538+ type(tRgn), intent(in) :: sub
539+ type(tRgn), intent(inout) :: pvt
540+ integer, intent(in), optional :: priority(n)
541+
542+ ! METIS variables
543+ integer(c_int), allocatable :: xadj(:), adjncy(:)
544+ integer(c_int), allocatable :: part(:)
545+ integer(c_int), allocatable, target :: w(:)
546+ integer(c_int) :: iret, nvtxs, ncon, nparts, old_objval, objval, opts(100) ! In 5.0.1 it is 40, but ...
547+ type(c_ptr) :: wp
548+
549+ interface
550+ integer(c_int) function METIS_SetDefaultOptions(opts) &
551+ bind(C, name="METIS_SetDefaultOptions")
552+ use iso_c_binding, only: c_int
553+ implicit none
554+ integer(c_int), dimension(*) :: opts
555+ end function METIS_SetDefaultOptions
556+ integer(c_int) function METIS_PartGraphKway(nvtxs,ncon,xadj,adjncy,vwgt, &
557+ vsize,adjwgt,nparts,tpwgts,ubvec,opts,objval,part) bind(C, name="METIS_PartGraphKway")
558+ use iso_c_binding, only: c_int, c_ptr
559+ implicit none
560+ integer(c_int) :: nvtxs, ncon, nparts, objval
561+ integer(c_int), dimension(*) :: xadj, adjncy, opts, part
562+ type(c_ptr), value :: vwgt, vsize, adjwgt, tpwgts, ubvec
563+ end function METIS_PartGraphKway
564+ end interface
565+
566+ ! variables for the loop
567+ integer :: i, ip, j
568+ integer :: old_bw, bw
569+ type(tRgn) :: next_pvt
570+
571+ call rgn_delete(pvt)
572+
573+ ! The following does C-style indexing
574+ ! as the internal METIS structure is a simple offset
575+
576+! call METIS_setdefaultoptions(opts)
577+ iret = METIS_setdefaultoptions(opts)
578+ ! METIS_OK == 1
579+ if ( iret /= 1 ) then
580+ opts(6) = 256 ! increase debug level and re-run for full dbg-lvl
581+ iret = METIS_setdefaultoptions(opts)
582+ call die('metis_PartGraphKway: Error on initializing default options.')
583+ end if
584+
585+ ! set options
586+ opts(2) = 0 ! OBJTYPE == edge-cut minimization
587+ opts(3) = 1 ! CTYPE == Sorted heavy-edge matching
588+! opts(5) = 1 ! RTYPE == Greedy-based cut and volume refinement
589+ opts(7) = 20 ! NITER(10) == Number of iterations
590+ opts(8) = 1 ! NCUTS == Number of cuts
591+ opts(10) = 1 ! NO2HOP == does not use 2 hop
592+ opts(11) = 1 ! MINCONN == Explicitly minimize the maximum connectivity
593+ opts(12) = 0 ! CONTIG == Forces contiguous
594+
595+ ! Allocate adjacency graphs
596+ call metis_adjacency_graph(n,nnzs,n_col,l_ptr,l_col,sub, &
597+ xadj, adjncy, w, priority)
598+
599+ allocate(part(sub%n))
600+
601+ ! Initialize the pivoting array
602+ call rgn_init(pvt,sub%n)
603+ call rgn_init(next_pvt,sub%n)
604+
605+ iret = 1
606+ nvtxs = sub%n
607+ ncon = 1
608+ nparts = 1
609+ old_bw = huge(1)
610+ wp = c_loc(w(1))
611+ do nparts = 2 , min(nvtxs / 2 + 1, nvtxs)
612+
613+ ! Call metis
614+ iret = METIS_PartGraphKway(nvtxs, ncon, xadj, adjncy, wp, &
615+ C_NULL_PTR, C_NULL_PTR, &
616+ nparts, & ! number of parts
617+ C_NULL_PTR, C_NULL_PTR, opts, objval, part)
618+
619+ ! An error forces us to exit loop
620+ if ( iret /= 1 ) exit
621+
622+ j = 0
623+ do ip = 0, nparts - 1
624+ do i = 1 , sub%n
625+ if ( part(i) == ip ) then
626+ j = j + 1
627+ next_pvt%r(j) = sub%r(i)
628+ end if
629+ end do
630+ end do
631+
632+ ! Transfer pivoting to actual pivoting index
633+ bw = bandwidth(n,nnzs,n_col,l_ptr,l_col,next_pvt)
634+ if ( bw == old_bw ) then
635+ if ( profile(n,nnzs,n_col,l_ptr,l_col,next_pvt) &
636+ < profile(n,nnzs,n_col,l_ptr,l_col,pvt) ) then
637+ pvt%r(:) = next_pvt%r(:)
638+ end if
639+ else if ( bw < old_bw ) then
640+ pvt%r(:) = next_pvt%r(:)
641+ end if
642+
643+ end do
644+
645+ if ( iret /= 1 ) then ! METIS_OK == 1
646+ print *,iret
647+ call die('metis_PartGraphKway: error in pivoting.')
648+ end if
649+
650+ ! Clean-up
651+ deallocate(xadj,adjncy,w,part)
652+ call rgn_delete(next_pvt)
653+
654+ if ( pvt%n /= sub%n ) call die('metis_PartGraphKway: Error in algorithm')
655+
656+ end subroutine metis_PartGraphKway_pvt
657+
658+ subroutine metis_PartGraphRecursive_pvt(n,nnzs,n_col,l_ptr,l_col,sub,pvt, priority)
659+ use iso_c_binding, only: c_int, c_ptr, c_loc, c_null_ptr
660+ integer, intent(in) :: n, nnzs
661+ integer, intent(in) :: n_col(n), l_ptr(n), l_col(nnzs)
662+ type(tRgn), intent(in) :: sub
663+ type(tRgn), intent(inout) :: pvt
664+ integer, intent(in), optional :: priority(n)
665+
666+ ! METIS variables
667+ integer(c_int), allocatable :: xadj(:), adjncy(:)
668+ integer(c_int), allocatable :: part(:)
669+ integer(c_int), allocatable, target :: w(:)
670+ integer(c_int) :: iret, nvtxs, ncon, nparts, old_objval, objval, opts(100) ! In 5.0.1 it is 40, but ...
671+ type(c_ptr) :: wp
672+
673+ interface
674+ integer(c_int) function METIS_SetDefaultOptions(opts) &
675+ bind(C, name="METIS_SetDefaultOptions")
676+ use iso_c_binding, only: c_int
677+ implicit none
678+ integer(c_int), dimension(*) :: opts
679+ end function METIS_SetDefaultOptions
680+ integer(c_int) function METIS_PartGraphRecursive(nvtxs,ncon,xadj,adjncy,vwgt, &
681+ vsize,adjwgt,nparts,tpwgts,ubvec,opts,objval,part) bind(C, name="METIS_PartGraphRecursive")
682+ use iso_c_binding, only: c_int, c_ptr
683+ implicit none
684+ integer(c_int) :: nvtxs, ncon, nparts, objval
685+ integer(c_int), dimension(*) :: xadj, adjncy, opts, part
686+ type(c_ptr), value :: vwgt, vsize, adjwgt, tpwgts, ubvec
687+ end function METIS_PartGraphRecursive
688+ end interface
689+
690+ ! variables for the loop
691+ integer :: i, ip, j
692+ integer :: old_bw, bw
693+ type(tRgn) :: next_pvt
694+
695+ call rgn_delete(pvt)
696+
697+ ! The following does C-style indexing
698+ ! as the internal METIS structure is a simple offset
699+
700+! call METIS_setdefaultoptions(opts)
701+ iret = METIS_setdefaultoptions(opts)
702+ ! METIS_OK == 1
703+ if ( iret /= 1 ) then
704+ opts(6) = 256 ! increase debug level and re-run for full dbg-lvl
705+ iret = METIS_setdefaultoptions(opts)
706+ call die('metis_PartGraphRecursive: Error on initializing default options.')
707+ end if
708+
709+ ! set options
710+ opts(2) = 0 ! OBJTYPE == edge-cut minimization
711+ opts(3) = 1 ! CTYPE == Sorted heavy-edge matching
712+! opts(5) = 1 ! RTYPE == Greedy-based cut and volume refinement
713+ opts(7) = 20 ! NITER(10) == Number of iterations
714+ opts(8) = 1 ! NCUTS == Number of cuts
715+ opts(10) = 1 ! NO2HOP == does not use 2 hop
716+ opts(11) = 1 ! MINCONN == Explicitly minimize the maximum connectivity
717+ opts(12) = 0 ! CONTIG == Forces contiguous
718+
719+ ! Allocate adjacency graphs
720+ call metis_adjacency_graph(n,nnzs,n_col,l_ptr,l_col,sub, &
721+ xadj, adjncy, w, priority)
722+
723+ allocate(part(sub%n))
724+
725+ ! Initialize the pivoting array
726+ call rgn_init(pvt,sub%n)
727+ call rgn_init(next_pvt,sub%n)
728+
729+ iret = 1
730+ nvtxs = sub%n
731+ ncon = 1
732+ nparts = 1
733+ old_bw = huge(1)
734+ wp = c_loc(w(1))
735+ do nparts = 2 , min(nvtxs / 2 + 1, nvtxs)
736+
737+ ! Call metis
738+ iret = METIS_PartGraphRecursive(nvtxs, ncon, xadj, adjncy, wp, &
739+ C_NULL_PTR, C_NULL_PTR, &
740+ nparts, & ! number of parts
741+ C_NULL_PTR, C_NULL_PTR, opts, objval, part)
742+
743+ ! An error forces us to exit loop
744+ if ( iret /= 1 ) exit
745+
746+ j = 0
747+ do ip = 0, nparts - 1
748+ do i = 1 , sub%n
749+ if ( part(i) == ip ) then
750+ j = j + 1
751+ next_pvt%r(j) = sub%r(i)
752+ end if
753+ end do
754+ end do
755+
756+ ! Transfer pivoting to actual pivoting index
757+ bw = bandwidth(n,nnzs,n_col,l_ptr,l_col,next_pvt)
758+ if ( bw == old_bw ) then
759+ if ( profile(n,nnzs,n_col,l_ptr,l_col,next_pvt) &
760+ < profile(n,nnzs,n_col,l_ptr,l_col,pvt) ) then
761+ pvt%r(:) = next_pvt%r(:)
762+ end if
763+ else if ( bw < old_bw ) then
764+ pvt%r(:) = next_pvt%r(:)
765+ end if
766+
767+ end do
768+
769+ if ( iret /= 1 ) then ! METIS_OK == 1
770+ print *,iret
771+ call die('metis_PartGraphRecursive: error in pivoting.')
772+ end if
773+
774+ ! Clean-up
775+ deallocate(xadj,adjncy,w,part)
776+ call rgn_delete(next_pvt)
777+
778+ if ( pvt%n /= sub%n ) call die('metis_PartGraphRecursive: Error in algorithm')
779+
780+ end subroutine metis_PartGraphRecursive_pvt
781 #endif
782
783
784@@ -2126,30 +2394,27 @@
785 function bandwidth(n,nnzs,n_col,l_ptr,l_col,sub) result(beta)
786 integer, intent(in) :: n, nnzs, n_col(n), l_ptr(n), l_col(nnzs)
787 type(tRgn), intent(in) :: sub
788- type(tRgn) :: s_sub, pvt
789+ type(tRgn) :: pvt
790 integer :: beta
791 integer :: i, j, ind, idx
792+
793+ call rgn_init(pvt, n, val=0)
794+ do i = 1, sub%n
795+ pvt%r(sub%r(i)) = i
796+ end do
797+
798 beta = 0
799-
800- call rgn_copy(sub,s_sub)
801- call rgn_sort(s_sub)
802- call rgn_init(pvt,sub%n)
803- do i = 1 , sub%n
804- j = rgn_pivot(s_sub,sub%r(i))
805- pvt%r(j) = i
806- end do
807-
808 do i = 1 , sub%n
809 idx = sub%r(i)
810 do ind = l_ptr(idx) + 1 , l_ptr(idx) + n_col(idx)
811 ! figure out the pivoting place
812- j = rgn_pivot(s_sub,l_col(ind))
813+ j = pvt%r(l_col(ind))
814 if ( j <= 0 ) cycle
815- beta = max(beta,i-pvt%r(j))
816+ beta = max(beta,i-j)
817 end do
818 end do
819
820- call rgn_delete(s_sub,pvt)
821+ call rgn_delete(pvt)
822
823 end function bandwidth
824
825@@ -2157,32 +2422,29 @@
826 integer, intent(in) :: n, nnzs, n_col(n), l_ptr(n), l_col(nnzs)
827 type(tRgn), intent(in) :: sub
828 integer(i8b) :: p
829- type(tRgn) :: s_sub, pvt
830+ type(tRgn) :: pvt
831 integer :: beta
832 integer :: i, j, ind, idx
833+
834+ call rgn_init(pvt, n, val=0)
835+ do i = 1, sub%n
836+ pvt%r(sub%r(i)) = i
837+ end do
838+
839 p = 0
840-
841- call rgn_copy(sub,s_sub)
842- call rgn_sort(s_sub)
843- call rgn_init(pvt,sub%n)
844- do i = 1 , sub%n
845- j = rgn_pivot(s_sub,sub%r(i))
846- pvt%r(j) = i
847- end do
848-
849 do i = 1 , sub%n
850 idx = sub%r(i)
851 beta = 0
852 do ind = l_ptr(idx) + 1 , l_ptr(idx) + n_col(idx)
853 ! figure out the pivoting place
854- j = rgn_pivot(s_sub,l_col(ind))
855+ j = pvt%r(l_col(ind))
856 if ( j <= 0 ) cycle
857- beta = max(beta,i-pvt%r(j))
858+ beta = max(beta,i-j)
859 end do
860 p = p + beta
861 end do
862
863- call rgn_delete(s_sub,pvt)
864+ call rgn_delete(pvt)
865
866 end function profile
867
868@@ -2558,8 +2820,19 @@
869 ! We will not follow the graph
870 if ( lonly_sub ) exit
871
872- idx = idx_degree(D_LOW,n,nnzs,n_col,l_ptr,l_col,sub, skip = skip, &
873+ ! Fake the skipping region
874+ ! This is just to skip the first couple of zeros
875+ call rgn_delete(con)
876+ do idx = 1, skip%n
877+ if ( skip%r(idx) > 0 ) then
878+ con%n = skip%n - idx + 1
879+ con%r => skip%r(idx:)
880+ exit
881+ end if
882+ end do
883+ idx = idx_degree(D_LOW,n,nnzs,n_col,l_ptr,l_col,sub, skip = con, &
884 priority = priority)
885+ call rgn_nullify(con)
886 etr = sub%r(idx)
887
888 ! Push the queue and the skip table
889@@ -2576,7 +2849,7 @@
890
891 ! Since the sort-degree is sorting into the same array, we have
892 ! to ensure con to have the correct size
893- call rgn_init(con, sub%n - pvt%n)
894+ call rgn_grow(con, sub%n - pvt%n)
895
896 ! 3. Create the connectivity graph from idx (this will remove "back"
897 ! connected entries, hence no dublicates needs to be taken into
898
899=== modified file 'Src/m_ts_cctype.f90'
900--- Src/m_ts_cctype.f90 2016-03-01 14:24:48 +0000
901+++ Src/m_ts_cctype.f90 2018-05-04 19:08:45 +0000
902@@ -61,6 +61,7 @@
903 integer, parameter :: CC_BOOLE_MIX = 103
904 integer, parameter :: CC_MID = 104
905 integer, parameter :: CC_CONTINUED_FRAC = 105
906+ integer, parameter :: CC_USER = 106
907
908
909 ! Converts a method to a string format
910@@ -116,7 +117,9 @@
911 case ( CC_MID )
912 str = 'Mid-rule'
913 case ( CC_CONTINUED_FRAC )
914- str = 'Continued fraction'
915+ str = 'Continued-fraction'
916+ case ( CC_USER )
917+ str = 'User'
918 case default
919 call die('Unknown method for the contour')
920 end select
921@@ -139,7 +142,9 @@
922 case ( CC_MID )
923 str = 'Mid-rule'
924 case ( CC_CONTINUED_FRAC )
925- str = 'Continued fraction'
926+ str = 'Continued-fraction'
927+ case ( CC_USER )
928+ str = 'User defined'
929 case default
930 call die('Unknown method for the contour')
931 end select
932@@ -175,6 +180,8 @@
933 str = 'Mid-rule'
934 case ( CC_CONTINUED_FRAC )
935 str = 'Continued fraction'
936+ case ( CC_USER )
937+ str = 'User defined'
938 case default
939 call die('Unknown method for the contour')
940 end select
941@@ -203,6 +210,9 @@
942 leqi(str,'continued-fraction') .or. &
943 leqi(str,'cont-frac') ) then
944 method = CC_CONTINUED_FRAC
945+ else if ( leqi(str,'file') .or. &
946+ leqi(str,'user') ) then
947+ method = CC_USER
948 else if ( leqi(str,'g-fermi') ) then
949 method = CC_G_NF_0kT
950 do i = G_NF_MIN_kT , G_NF_MAX_kT
951
952=== modified file 'Src/m_ts_contour_eq.f90'
953--- Src/m_ts_contour_eq.f90 2017-10-23 09:18:56 +0000
954+++ Src/m_ts_contour_eq.f90 2018-05-04 19:08:45 +0000
955@@ -442,7 +442,11 @@
956 ! and not in "random" order
957 idx = get_c_io_index(mu%Eq_seg(i))
958
959- if ( leqi(Eq_c(idx)%c_io%part,'circle') ) then
960+ if ( leqi(Eq_c(idx)%c_io%part,'user') ) then
961+
962+ call contour_file(Eq_c(idx),mu,lift)
963+
964+ else if ( leqi(Eq_c(idx)%c_io%part,'circle') ) then
965
966 call contour_Circle(Eq_c(idx),mu,R,cR)
967
968@@ -513,7 +517,7 @@
969
970 ! the radius can be calculated using two triangles in the circle
971 ! there is no need to use the cosine-relations
972- R = .5_dp * cR / cos(alpha) ** 2
973+ R = 0.5_dp * cR / cos(alpha) ** 2
974
975 ! the real-axis center
976 cR = a + R
977@@ -1127,34 +1131,47 @@
978 call TanhSinh_Exact(c%c_io%N,ce,cw,a,b, p=tmp)
979
980 end if
981-
982-
983+
984+ case ( CC_USER )
985+
986+ ! Read the file information
987+ call contour_file(c,mu,Eta)
988+
989 case default
990 write(*,*) 'Method for contour ',trim(c%c_io%name), &
991 ' could not be deciphered: ', c%c_io%method
992 call die('Could not determine the line-integral')
993 end select
994-
995- ! I know this is "bad" practice, however, zero is a well-defined quantity.
996- set_c = sum(abs(c%c(:))) == 0._dp
997-
998+
999 ! get the index in the ID array (same index in w-array)
1000 call ID2idx(c,mu%ID,idx)
1001-
1002- do i = 1 , c%c_io%N
1003- if ( set_c ) then
1004+
1005+ if ( method(c%c_io) == CC_USER ) then
1006+
1007+ do i = 1 , c%c_io%N
1008+ c%w(idx,i) = c%w(idx,i) * nf((real(c%c(i), dp) - mu%mu) / mu%kT)
1009+ end do
1010+
1011+ else
1012+
1013+ ! I know this is "bad" practice, however, zero is a well-defined quantity.
1014+ set_c = sum(abs(c%c(:))) == 0._dp
1015+
1016+ do i = 1 , c%c_io%N
1017+ if ( set_c ) then
1018 c%c(i) = dcmplx(ce(i),Eta)
1019- else
1020+ else
1021 if ( abs(c%c(i) - dcmplx(ce(i),Eta)) > 1.e-10_dp ) then
1022- call die('contour_line: Error on contour match')
1023+ call die('contour_line: Error on contour match')
1024 end if
1025- end if
1026-
1027- !ztmp = (c%c(i) - mu%mu) / mu%kT
1028- c%w(idx,i) = cw(i) * nf((ce(i) - mu%mu) / mu%kT)
1029-
1030- end do
1031-
1032+ end if
1033+
1034+ c%w(idx,i) = cw(i) * nf((ce(i) - mu%mu) / mu%kT)
1035+
1036+ end do
1037+
1038+ end if
1039+
1040 deallocate(ce,cw)
1041
1042 end subroutine contour_line
1043@@ -1256,7 +1273,9 @@
1044
1045 case default
1046
1047- ! we revert so that we can actually use the line-integral
1048+ ! we revert so that we can actually use the line-integral
1049+ ! The tail and line are equivalent in the sense that the
1050+ ! fermi functions are applied to the weights
1051 c%c_io%part = 'line'
1052
1053 call contour_line(c,mu,Eta)
1054@@ -1438,6 +1457,110 @@
1055
1056 end subroutine contour_continued_fraction
1057
1058+ ! This routine will read the contour points from a file
1059+ subroutine contour_file(c,mu,Eta)
1060+ use m_io, only: io_assign, io_close
1061+ use fdf, only: fdf_convfac
1062+
1063+ type(ts_cw), intent(inout) :: c
1064+ type(ts_mu), intent(in) :: mu
1065+ ! The lifting into the complex plane
1066+ real(dp), intent(in) :: Eta
1067+
1068+ integer :: iu, iostat, ne, idx
1069+ logical :: exist
1070+ complex(dp) :: E , W
1071+ real(dp) :: rE, iE, rW, iW, conv
1072+ character(len=512) :: file, line
1073+ character(len=16) :: unit
1074+
1075+ ! The contour type contains the file name in:
1076+ ! c%c_io%cN (weirdly enough)
1077+ file = c%c_io%cN
1078+ call ID2idx(c,mu%ID,idx)
1079+
1080+ call io_assign(iu)
1081+
1082+ ! Open the contour file
1083+ inquire(file=trim(file), exist=exist)
1084+ if ( .not. exist ) then
1085+ call die('The file: '//trim(file)//' could not be found to read contour points!')
1086+ end if
1087+
1088+ ! Open the file
1089+ open(iu, file=trim(file), form='formatted', status='old')
1090+
1091+ ne = 0
1092+ ! The default unit is eV.
1093+ ! On every line an optional unit-specificer may be used to specify the
1094+ ! subsequent lines units (until another unit is specified)
1095+ conv = fdf_convfac('eV', 'Ry')
1096+ do
1097+ ! Now we have the line
1098+ read(iu, '(a)', iostat=iostat) line
1099+ if ( iostat /= 0 ) exit
1100+ if ( len_trim(line) == 0 ) cycle
1101+ line = trim(adjustl(line))
1102+ if ( line(1:1) == '#' ) cycle
1103+
1104+ ! We have a line with energy and weight
1105+ ne = ne + 1
1106+ ! There are three optional ways of reading this
1107+ ! 1. ReE ImE, ReW ImW [unit]
1108+ read(line, *, iostat=iostat) rE, iE, rW, iW, unit
1109+ if ( iostat == 0 ) then
1110+ conv = fdf_convfac(unit, 'Ry')
1111+ else
1112+ read(line, *, iostat=iostat) rE, iE, rW, iW
1113+ end if
1114+ if ( iostat == 0 ) then
1115+ c%c(ne) = dcmplx(rE,iE) * conv
1116+ c%w(idx,ne) = dcmplx(rW,iW) * conv
1117+ cycle
1118+ end if
1119+
1120+ ! 2. ReE ImE, ReW [unit]
1121+ iW = 0._dp
1122+ read(line, *, iostat=iostat) rE, iE, rW, unit
1123+ if ( iostat == 0 ) then
1124+ conv = fdf_convfac(unit, 'Ry')
1125+ else
1126+ read(line, *, iostat=iostat) rE, iE, rW
1127+ end if
1128+ if ( iostat == 0 ) then
1129+ c%c(ne) = dcmplx(rE,iE) * conv
1130+ c%w(idx,ne) = dcmplx(rW,iW) * conv
1131+ cycle
1132+ end if
1133+
1134+ ! 3. ReE , ReW [unit]
1135+ iE = Eta
1136+ iW = 0._dp
1137+ read(line, *, iostat=iostat) rE, rW, unit
1138+ if ( iostat == 0 ) then
1139+ conv = fdf_convfac(unit, 'Ry')
1140+ else
1141+ read(line, *, iostat=iostat) rE, rW
1142+ end if
1143+ if ( iostat == 0 ) then
1144+ c%c(ne) = dcmplx(rE * conv,iE)
1145+ c%w(idx,ne) = dcmplx(rW,iW) * conv
1146+ cycle
1147+ end if
1148+
1149+ call die('Contour file: '//trim(file)//' is not formatted correctly. &
1150+ &Please read the documentation!')
1151+
1152+ end do
1153+
1154+ call io_close(iu)
1155+
1156+ if ( c%c_io%N /= ne ) then
1157+ call die('Error in reading the contour points from file: '//trim(file))
1158+ end if
1159+
1160+ end subroutine contour_file
1161+
1162 function Eq_E(id,step) result(c)
1163 integer, intent(in) :: id
1164 integer, intent(in), optional :: step
1165
1166=== modified file 'Src/m_ts_contour_neq.f90'
1167--- Src/m_ts_contour_neq.f90 2017-08-22 15:09:30 +0000
1168+++ Src/m_ts_contour_neq.f90 2018-05-04 19:08:45 +0000
1169@@ -449,22 +449,26 @@
1170 type(ts_cw), intent(inout) :: c
1171 real(dp), intent(in) :: Eta
1172
1173- if ( leqi(c%c_io%part,'line') ) then
1174-
1175- call contour_line(c,Eta)
1176-
1177+ if ( leqi(c%c_io%part,'user') ) then
1178+
1179+ call contour_file(c,Eta)
1180+
1181+ else if ( leqi(c%c_io%part,'line') ) then
1182+
1183+ call contour_line(c,Eta)
1184+
1185 else if ( leqi(c%c_io%part,'tail') ) then
1186
1187- c%c_io%part = 'line'
1188-
1189- call contour_line(c,Eta)
1190-
1191- c%c_io%part = 'tail'
1192+ c%c_io%part = 'line'
1193+
1194+ call contour_line(c,Eta)
1195+
1196+ c%c_io%part = 'tail'
1197
1198 else
1199-
1200- call neq_die('Unrecognized contour type for the &
1201- &non-equilibrium part.')
1202+
1203+ call neq_die('Unrecognized contour type for the &
1204+ &non-equilibrium part.')
1205
1206 end if
1207
1208@@ -602,6 +606,14 @@
1209 end if
1210
1211 call TanhSinh_Exact(c%c_io%N,ce,cw,a,b, p=tmp)
1212+
1213+ case ( CC_USER )
1214+
1215+ call contour_file(c, Eta)
1216+
1217+ ! Immediately return as the user has specified *everything*
1218+ deallocate(ce, cw)
1219+ return
1220
1221 case default
1222
1223@@ -616,6 +628,109 @@
1224
1225 end subroutine contour_line
1226
1227+
1228+ ! This routine will read the contour points from a file
1229+ subroutine contour_file(c,Eta)
1230+ use m_io, only: io_assign, io_close
1231+ use fdf, only: fdf_convfac
1232+
1233+ type(ts_cw), intent(inout) :: c
1234+ ! The lifting into the complex plane
1235+ real(dp), intent(in) :: Eta
1236+
1237+ integer :: iu, iostat, ne
1238+ logical :: exist
1239+ complex(dp) :: E , W
1240+ real(dp) :: rE, iE, rW, iW, conv
1241+ character(len=512) :: file, line
1242+ character(len=16) :: unit
1243+
1244+ ! The contour type contains the file name in:
1245+ ! c%c_io%cN (weirdly enough)
1246+ file = c%c_io%cN
1247+
1248+ call io_assign(iu)
1249+
1250+ ! Open the contour file
1251+ inquire(file=trim(file), exist=exist)
1252+ if ( .not. exist ) then
1253+ call die('The file: '//trim(file)//' could not be found to read contour points!')
1254+ end if
1255+
1256+ ! Open the file
1257+ open(iu, file=trim(file), form='formatted', status='old')
1258+
1259+ ne = 0
1260+ ! The default unit is eV.
1261+ ! On every line an optional unit-specificer may be used to specify the
1262+ ! subsequent lines units (until another unit is specified)
1263+ conv = fdf_convfac('eV', 'Ry')
1264+ do
1265+ ! Now we have the line
1266+ read(iu, '(a)', iostat=iostat) line
1267+ if ( iostat /= 0 ) exit
1268+ if ( len_trim(line) == 0 ) cycle
1269+ line = trim(adjustl(line))
1270+ if ( line(1:1) == '#' ) cycle
1271+
1272+ ! We have a line with energy and weight
1273+ ne = ne + 1
1274+ ! There are three optional ways of reading this
1275+ ! 1. ReE ImE, ReW ImW [unit]
1276+ read(line, *, iostat=iostat) rE, iE, rW, iW, unit
1277+ if ( iostat == 0 ) then
1278+ conv = fdf_convfac(unit, 'Ry')
1279+ else
1280+ read(line, *, iostat=iostat) rE, iE, rW, iW
1281+ end if
1282+ if ( iostat == 0 ) then
1283+ c%c(ne) = dcmplx(rE,iE) * conv
1284+ c%w(ne,1) = dcmplx(rW,iW) * conv
1285+ cycle
1286+ end if
1287+
1288+ ! 2. ReE ImE, ReW [unit]
1289+ iW = 0._dp
1290+ read(line, *, iostat=iostat) rE, iE, rW, unit
1291+ if ( iostat == 0 ) then
1292+ conv = fdf_convfac(unit, 'Ry')
1293+ else
1294+ read(line, *, iostat=iostat) rE, iE, rW
1295+ end if
1296+ if ( iostat == 0 ) then
1297+ c%c(ne) = dcmplx(rE,iE) * conv
1298+ c%w(ne,1) = dcmplx(rW,iW) * conv
1299+ cycle
1300+ end if
1301+
1302+ ! 3. ReE , ReW [unit]
1303+ iE = Eta
1304+ iW = 0._dp
1305+ read(line, *, iostat=iostat) rE, rW, unit
1306+ if ( iostat == 0 ) then
1307+ conv = fdf_convfac(unit, 'Ry')
1308+ else
1309+ read(line, *, iostat=iostat) rE, rW
1310+ end if
1311+ if ( iostat == 0 ) then
1312+ c%c(ne) = dcmplx(rE * conv,iE)
1313+ c%w(ne,1) = dcmplx(rW,iW) * conv
1314+ cycle
1315+ end if
1316+
1317+ call die('Contour file: '//trim(file)//' is not formatted correctly. &
1318+ &Please read the documentation!')
1319+
1320+ end do
1321+
1322+ call io_close(iu)
1323+
1324+ if ( c%c_io%N /= ne ) then
1325+ call die('Error in reading the contour points from file: '//trim(file))
1326+ end if
1327+
1328+ end subroutine contour_file
1329+
1330 function nEq_E(id,step) result(c)
1331 integer, intent(in) :: id
1332 integer, intent(in), optional :: step
1333
1334=== modified file 'Src/m_ts_io_ctype.f90'
1335--- Src/m_ts_io_ctype.f90 2016-04-27 12:13:56 +0000
1336+++ Src/m_ts_io_ctype.f90 2018-05-04 19:08:45 +0000
1337@@ -264,6 +264,7 @@
1338
1339 character(len=c_N) :: opt, val
1340 integer :: iS, iE
1341+ logical :: is_file
1342
1343 ! if the block does not exist, return
1344 if ( .not. ts_exists_contour_block(prefix,suffix,bName,bfdf=bfdf) ) then
1345@@ -277,7 +278,7 @@
1346 c%name = trim(bName)
1347
1348 ! We must ensure the block be organized as this:
1349- ! part circle|line|tail
1350+ ! part circle|line|tail|user
1351 ! from <a> to <b>
1352 ! points <N> / separation <d>
1353 ! method <method>
1354@@ -312,8 +313,10 @@
1355 c%part = 'line'
1356 else if ( leqi(c%part,'tail') ) then
1357 c%part = 'tail'
1358+ else if ( leqi(c%part,'user') ) then
1359+ c%part = 'user'
1360 else
1361- call die('Part of the contour could not be recognized as circle|square|line|tail')
1362+ call die('Part of the contour could not be recognized as circle|square|line|tail|user')
1363 end if
1364
1365
1366@@ -361,17 +364,30 @@
1367 end if
1368
1369 ! we now read the points or separation
1370+ is_file = .false.
1371 iS = search_fun('points',pline)
1372 if ( iS < 0 ) iS = search_fun('p',pline)
1373 iE = search_fun('delta',pline)
1374- if ( iE < 0 ) iE = search_fun('sep',pline)
1375+ if ( iE < 0 ) iE = search_fun('d',pline)
1376 if ( iS < 0 .and. iE < 0 ) then
1377- call die('Block: '//trim(bName)//' is not build correctly. &
1378- &Could not decipher points/delta/separation')
1379+ iS = search_fun('file',pline)
1380+ if ( iS < 0 ) iS = search_fun('user',pline)
1381+ if ( iS < 0 ) then
1382+ call die('Block: '//trim(bName)//' is not build correctly. &
1383+ &Could not decipher points/delta/file')
1384+ end if
1385+ is_file = .true.
1386 end if
1387
1388 ! if we have points we simply read in the number
1389- if ( 0 <= iS ) then
1390+ if ( is_file ) then
1391+
1392+ ! The file contains all the relevant information.
1393+ c%cN = fdf_bnames(pline, 2) ! file name
1394+ c%method = 'user' ! user-defined method
1395+ c%N = file_energy_points(c%cN) ! read number of energy points
1396+
1397+ else if ( 0 <= iS ) then
1398 c%N = fdf_bintegers(pline,1,after=iS) ! first integer
1399 c%cN = characters(pline,1,-1,after=iS)
1400 if ( c%N < 1 ) then
1401@@ -397,17 +413,30 @@
1402 ! } "points"
1403
1404 ! { "method <method>"
1405- if ( .not. move2names() ) then
1406- call die('Block: '//trim(bName)//'. &
1407+ if ( move2names() ) then
1408+ val = fdf_bnames(pline, 1)
1409+ if ( leqi(val, 'method') ) then
1410+ if ( fdf_bnnames(pline) < 2 ) then
1411+ call die('Block: '//trim(bName)//' has not described the method properly. &
1412+ &Must have method <method>')
1413+ end if
1414+
1415+ ! the method should be a one-name thing
1416+ c%method = fdf_bnames(pline,2)
1417+
1418+ else if ( .not. is_file ) then
1419+ ! The method segment has not been found.
1420+ ! Error out
1421+ call die('Block: '//trim(bName)//'. &
1422 &Could not find method <method> segment in contour')
1423- end if
1424- if ( fdf_bnnames(pline) < 2 ) then
1425- call die('Block: '//trim(bName)//' has not described the method properly. &
1426- &Must have method <method>')
1427- end if
1428-
1429- ! the method should be a one-name thing
1430- c%method = fdf_bnames(pline,2)
1431+ else if ( is_file ) then
1432+ ! The name is most probably an option, step back in the block
1433+ if ( .not. fdf_bbackspace(bfdf) ) then
1434+ call die('Block: '//trim(bName)//' parsing went wrong!')
1435+ end if
1436+ end if
1437+ end if
1438+ if ( is_file ) c%method = 'user'
1439
1440 ! } "method"
1441
1442@@ -432,7 +461,43 @@
1443 end do
1444 ! } "opt"
1445
1446- contains
1447+ contains
1448+
1449+ function file_energy_points(file) result(ne)
1450+ use m_io, only: io_assign, io_close
1451+
1452+ character(len=*), intent(in) :: file
1453+ integer :: iu
1454+ character(len=256) :: line
1455+ integer :: ne, iostat
1456+ logical :: exist
1457+
1458+ call io_assign(iu)
1459+
1460+ ! Open the contour file
1461+ inquire(file=trim(file), exist=exist)
1462+ if ( .not. exist ) then
1463+ call die('Block: '//trim(bName)//' requested an external contour file. &
1464+ &The file: '//trim(file)//' could not be found!')
1465+ end if
1466+
1467+ ! Open the file
1468+ open(iu, file=trim(file), form='formatted', status='old')
1469+
1470+ ne = 0
1471+ do
1472+ read(iu, '(a)', iostat=iostat) line
1473+ if ( iostat /= 0 ) exit
1474+ if ( len_trim(line) == 0 ) cycle
1475+ line = trim(adjustl(line))
1476+ if ( line(1:1) == '#' ) cycle
1477+
1478+ ne = ne + 1
1479+ end do
1480+
1481+ call io_close(iu)
1482+
1483+ end function file_energy_points
1484
1485 function move2names() result(found)
1486 logical :: found
1487@@ -804,13 +869,17 @@
1488
1489 write(*,'(4a)') ' from ',trim(c%ca),' to ',trim(c%cb)
1490
1491- if ( len_trim(c%cd) /= 0 ) then
1492- ! we have delta designation
1493- write(*,'(t7,a,tr1,a)') 'delta', trim(c%cd)
1494-
1495+ ! Ensure we correctly get the user-definition
1496+ if ( c%method == 'user' ) then
1497+ write(*,'(t7,a,tr1,a)') 'file', trim(c%cN)
1498+
1499+ else if ( len_trim(c%cd) /= 0 ) then
1500+ ! we have delta designation
1501+ write(*,'(t7,a,tr1,a)') 'delta', trim(c%cd)
1502+
1503 else
1504- ! Print the number of points...
1505- write(*,'(t7,a,tr1,i0)') 'points', c%N
1506+ ! Print the number of points...
1507+ write(*,'(t7,a,tr1,i0)') 'points', c%N
1508
1509 end if
1510
1511@@ -831,6 +900,7 @@
1512
1513 end subroutine ts_print_contour_block
1514
1515+
1516 ! *****
1517 ! This routine fixes the inputs for the contours according to those given by
1518 ! the input electrode
1519
1520=== modified file 'Src/m_ts_method.f90'
1521--- Src/m_ts_method.f90 2018-02-27 21:03:50 +0000
1522+++ Src/m_ts_method.f90 2018-05-04 19:08:45 +0000
1523@@ -210,6 +210,10 @@
1524 subroutine set_type(typ,ia,na_u,lasto)
1525 integer, intent(in) :: typ, ia, na_u,lasto(0:na_u)
1526 integer :: i, no
1527+ if ( ia > na_u ) then
1528+ call die('Error in specifying the type of an atom!. &
1529+ &Atoms specified is above the total number of atoms!')
1530+ end if
1531 if ( a_type(ia) /= TYP_DEVICE ) then
1532 write(*,'(2(a,i0))') 'Trying to set atom ',ia,' to type: ',typ
1533 write(*,'(2(a,i0))') 'Atom ',ia,' is already: ',a_type(ia)
1534
1535=== modified file 'Src/m_ts_options.F90'
1536--- Src/m_ts_options.F90 2018-04-06 19:25:57 +0000
1537+++ Src/m_ts_options.F90 2018-05-04 19:08:45 +0000
1538@@ -182,7 +182,7 @@
1539 ts_method = TS_MUMPS
1540 #endif
1541 else
1542- call die('Unrecognized Transiesta solution method: '//trim(chars))
1543+ call die('Unrecognized TranSiesta solution method: '//trim(chars))
1544 end if
1545
1546 ! currently this does not work
1547@@ -251,7 +251,7 @@
1548
1549 ts_kT = fdf_get('TS.ElectronicTemperature',kT,'Ry')
1550 if ( ts_kT / Kelvin < 10._dp ) then
1551- call die('transiesta electronic temperature *must* &
1552+ call die('TranSiesta electronic temperature *must* &
1553 &be larger than 10 kT')
1554 end if
1555
1556@@ -277,7 +277,7 @@
1557 ! We do not allow the electronic temperature
1558 ! to be below 10 kT
1559 if ( mus(i)%kT / Kelvin < 10._dp ) then
1560- call die('transiesta electronic temperature *must* &
1561+ call die('TranSiesta electronic temperature *must* &
1562 &be larger than 10 kT')
1563 end if
1564
1565@@ -1023,7 +1023,7 @@
1566 end select
1567 end if
1568 if ( .not. Calc_Forces ) then
1569- write(*,f11) '*** TranSIESTA will NOT update forces ***'
1570+ write(*,f11) '*** TranSiesta will NOT update forces ***'
1571 end if
1572
1573 if ( TS_RHOCORR_METHOD == 0 ) then
1574@@ -1112,17 +1112,17 @@
1575
1576 write(*,'(3a)') repeat('*',24),' Begin: TS CHECKS AND WARNINGS ',repeat('*',24)
1577 if ( FixSpin .and. (TS_HS_save .or. TSmode) ) then
1578- write(*,'(a)') 'Fixed spin not possible with TranSIESTA!'
1579+ write(*,'(a)') 'Fixed spin not possible with TranSiesta!'
1580 write(*,'(a)') 'Disable TS.HS.Save or FixSpin'
1581- write(*,'(a)') 'Electrodes with fixed spin is not possible with Transiesta!'
1582- call die('Fixing spin is not possible in transiesta')
1583+ write(*,'(a)') 'Electrodes with fixed spin is not possible with TranSiesta!'
1584+ call die('Fixing spin is not possible in TranSiesta')
1585 end if
1586
1587 if ( .not. TSmode ) then
1588 if ( TS_HA == TS_HA_ELEC ) then
1589- call die('Hartree potiental cannot use electrodes without transiesta')
1590+ call die('Hartree potiental cannot use electrodes without TranSiesta')
1591 else if ( TS_HA == TS_HA_ELEC_BOX ) then
1592- call die('Hartree potiental cannot use electrodes without transiesta')
1593+ call die('Hartree potiental cannot use electrodes without TranSiesta')
1594 end if
1595 end if
1596
1597@@ -1148,7 +1148,7 @@
1598 end if
1599
1600 if ( TS_HA == TS_HA_NONE ) then
1601- write(*,'(a)') 'Hartree potiental fix REQUIRED when running transiesta'
1602+ write(*,'(a)') 'Hartree potiental fix REQUIRED when running TranSiesta'
1603 err = .true.
1604 end if
1605
1606@@ -1310,17 +1310,17 @@
1607 call contour_nEq_warnings()
1608
1609 if ( .not. Calc_Forces ) then
1610- write(*,f11) '*** TranSIESTA will NOT update forces ***'
1611+ write(*,f11) '*** TranSiesta will NOT update forces ***'
1612 write(*,f11) '*** ALL FORCES AFTER TRANSIESTA HAS RUN ARE WRONG ***'
1613 if ( Nmove > 0 ) then
1614- write(*,'(a)')'Relaxation with transiesta *REQUIRES* an update of &
1615+ write(*,'(a)')'Relaxation with TranSiesta *REQUIRES* an update of &
1616 &the energy density matrix. Will continue at your request.'
1617 err = .true.
1618 end if
1619 end if
1620
1621 if ( Nmove > 0 .and. .not. all(Elecs(:)%DM_update > 0) ) then
1622- write(*,'(a)') 'transiesta relaxation is only allowed if you also &
1623+ write(*,'(a)') 'TranSiesta relaxation is only allowed if you also &
1624 &update, at least, the cross terms, please set: &
1625 &TS.Elecs.DM.Update [cross-terms|all]'
1626 err = .true.
1627@@ -1382,7 +1382,7 @@
1628
1629 if ( ts_tidx < 1 ) then
1630
1631- write(*,'(a)') '*** TranSIESTA semi-infinite directions are individual ***'
1632+ write(*,'(a)') '*** TranSiesta semi-infinite directions are individual ***'
1633 write(*,'(a)') '*** It is heavily adviced to have any electrodes with no &
1634 &periodicity'
1635 write(*,'(a)') ' in the transverse directions be located as far from any &
1636@@ -1626,7 +1626,7 @@
1637 write(*,'(tr19,a)') 'TRANSIESTA REPORTED ERRORS'
1638 write(*,'(tr18,a)') repeat('*',30)
1639
1640- call die('One or more errors have occured doing transiesta &
1641+ call die('One or more errors have occured doing TranSiesta &
1642 &initialization, check the output')
1643 end if
1644
1645@@ -1654,13 +1654,13 @@
1646
1647 if ( onlyS .or. .not. TSmode ) return
1648
1649- write(*,'(/,a,/)') '>>> Transiesta block information for FDF-file START <<<'
1650+ write(*,'(/,a,/)') '>>> TranSiesta block information for FDF-file START <<<'
1651
1652 call print_mus_block( 'TS' , N_mu , mus)
1653
1654 call print_contour_block( 'TS' , IsVolt )
1655
1656- write(*,'(/,a,/)') '>>> Transiesta block information for FDF-file END <<<'
1657+ write(*,'(/,a,/)') '>>> TranSiesta block information for FDF-file END <<<'
1658
1659 ! write out the contour
1660 call io_contour(IsVolt, mus, slabel)
1661
1662=== modified file 'Src/m_ts_pivot.F90'
1663--- Src/m_ts_pivot.F90 2018-03-26 19:52:10 +0000
1664+++ Src/m_ts_pivot.F90 2018-05-04 19:08:45 +0000
1665@@ -314,18 +314,41 @@
1666 call sp_pvt(n,tmp_Sp,r_pvt, PVT_PCG, c_pvt, start = r_Els, only_sub = .not. lextend )
1667
1668 #ifdef SIESTA__METIS
1669- else if ( str_contain(pvt_str,'metis+priority') ) then
1670- str_tmp = trim(str_tmp)//'+metis+priority'
1671+ else if ( str_contain(pvt_str,'metis+priority') .or. &
1672+ str_contain(pvt_str,'nodend+priority') ) then
1673+ str_tmp = trim(str_tmp)//'+nodend+priority'
1674
1675- call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS, c_pvt, &
1676+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_NODEND, c_pvt, &
1677 priority = priority%r)
1678- else if ( str_contain(pvt_str,'metis') ) then
1679- str_tmp = trim(str_tmp)//'+metis'
1680-
1681- call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS, c_pvt)
1682+ else if ( str_contain(pvt_str,'metis') .or. &
1683+ str_contain(pvt_str,'nodend') ) then
1684+ str_tmp = trim(str_tmp)//'+nodend'
1685+
1686+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_NODEND, c_pvt)
1687+
1688+ else if ( str_contain(pvt_str,'partgraphkway+priority') ) then
1689+ str_tmp = trim(str_tmp)//'+partgraphkway+priority'
1690+
1691+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_PARTGRAPHKWAY, c_pvt, &
1692+ priority = priority%r)
1693+
1694+ else if ( str_contain(pvt_str,'partgraphkway') ) then
1695+ str_tmp = trim(str_tmp)//'+partgraphkway'
1696+
1697+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_PARTGRAPHKWAY, c_pvt)
1698+
1699+ else if ( str_contain(pvt_str,'partgraphrecursive+priority') ) then
1700+ str_tmp = trim(str_tmp)//'+partgraphrecursive+priority'
1701+
1702+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_PARTGRAPHRECURSIVE, c_pvt, &
1703+ priority = priority%r)
1704+
1705+ else if ( str_contain(pvt_str,'partgraphrecursive') ) then
1706+ str_tmp = trim(str_tmp)//'+partgraphrecursive'
1707+
1708+ call sp_pvt(n,tmp_Sp,r_pvt, PVT_METIS_PARTGRAPHRECURSIVE, c_pvt)
1709
1710 #endif
1711-
1712 else if ( str_contain(pvt_str,'CG') .or. pvt_option == PVT_NONE ) then
1713
1714 is_rev = str_contain(pvt_str, 'rev-')
1715
1716=== modified file 'Src/m_ts_tri_init.F90'
1717--- Src/m_ts_tri_init.F90 2018-04-07 18:57:43 +0000
1718+++ Src/m_ts_tri_init.F90 2018-05-04 19:08:45 +0000
1719@@ -631,6 +631,69 @@
1720 call tri(r_El)
1721 end if
1722
1723+#ifdef SIESTA__METIS
1724+ fmethod = trim(corb)//'+NodeND+priority'
1725+ if ( IONode ) write(*,fmt) trim(corb),'NodeND+priority'
1726+ call sp_pvt(n,tmpSp2,r_tmp, PVT_METIS_NODEND, sub = full, priority = priority%r)
1727+ if ( orb_atom == 1 ) then
1728+ call tri(r_tmp)
1729+ else
1730+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1731+ call tri(r_El)
1732+ end if
1733+
1734+ fmethod = trim(corb)//'+rev-NodeND+priority'
1735+ if ( IONode ) write(*,fmt) trim(corb),'rev-NodeND+priority'
1736+ call rgn_reverse(r_tmp)
1737+ if ( orb_atom == 1 ) then
1738+ call tri(r_tmp)
1739+ else
1740+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1741+ call tri(r_El)
1742+ end if
1743+
1744+ fmethod = trim(corb)//'+PartGraphKway+priority'
1745+ if ( IONode ) write(*,fmt) trim(corb),'PartGraphKway+priority'
1746+ call sp_pvt(n,tmpSp2,r_tmp, PVT_METIS_PARTGRAPHKWAY, sub = full, priority = priority%r)
1747+ if ( orb_atom == 1 ) then
1748+ call tri(r_tmp)
1749+ else
1750+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1751+ call tri(r_El)
1752+ end if
1753+
1754+ fmethod = trim(corb)//'+rev-PartGraphKway+priority'
1755+ if ( IONode ) write(*,fmt) trim(corb),'rev-PartGraphKway+priority'
1756+ call rgn_reverse(r_tmp)
1757+ if ( orb_atom == 1 ) then
1758+ call tri(r_tmp)
1759+ else
1760+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1761+ call tri(r_El)
1762+ end if
1763+
1764+ fmethod = trim(corb)//'+PartGraphRecursive+priority'
1765+ if ( IONode ) write(*,fmt) trim(corb),'PartGraphRecursive+priority'
1766+ call sp_pvt(n,tmpSp2,r_tmp, PVT_METIS_PARTGRAPHRECURSIVE, sub = full, priority = priority%r)
1767+ if ( orb_atom == 1 ) then
1768+ call tri(r_tmp)
1769+ else
1770+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1771+ call tri(r_El)
1772+ end if
1773+
1774+ fmethod = trim(corb)//'+rev-PartGraphRecursive+priority'
1775+ if ( IONode ) write(*,fmt) trim(corb),'rev-PartGraphRecursive+priority'
1776+ call rgn_reverse(r_tmp)
1777+ if ( orb_atom == 1 ) then
1778+ call tri(r_tmp)
1779+ else
1780+ call rgn_atom2orb(r_tmp,na_u,lasto,r_El)
1781+ call tri(r_El)
1782+ end if
1783+
1784+#endif
1785+
1786 end do orb_atom_switch
1787
1788 call rgn_delete(r_tmp,r_El,full,priority)
1789
1790=== modified file 'Util/SpPivot/pvtsp.F90'
1791--- Util/SpPivot/pvtsp.F90 2018-04-06 17:22:45 +0000
1792+++ Util/SpPivot/pvtsp.F90 2018-05-04 19:08:45 +0000
1793@@ -144,9 +144,15 @@
1794 fmethod = 'Scramble'
1795
1796 #ifdef SIESTA__METIS
1797- case ( '-metis' )
1798- method = PVT_METIS
1799- fmethod = 'Metis'
1800+ case ( '-metis', '-nodend' )
1801+ method = PVT_METIS_NODEND
1802+ fmethod = 'metis-NodeND'
1803+ case ( '-partgraphkway' )
1804+ method = PVT_METIS_PARTGRAPHKWAY
1805+ fmethod = 'metis-PartGraphKway'
1806+ case ( '-partgraphrecursive' )
1807+ method = PVT_METIS_PARTGRAPHRECURSIVE
1808+ fmethod = 'metis-PartGraphRecursive'
1809 #endif
1810
1811 case ( '-w', '-weight' )
1812@@ -388,9 +394,9 @@
1813
1814 subroutine help()
1815 character(len=20), parameter :: gf = '(tr3,a,'':'',/,tr8,a)'
1816- character(len=10), parameter :: nf = '(tr8,a)'
1817+ character(len=*), parameter :: nf = '(tr8,a)'
1818
1819- character(len=10), parameter :: fm = '(tr11,a)'
1820+ character(len=*), parameter :: fm = '(tr11,a18,": ",a)'
1821
1822 write(*,'(a)') 'The following options are available for pvtsp:'
1823 write(*,'(a)')
1824@@ -401,18 +407,20 @@
1825 write(*,gf) '--metis-stdout','make METIS output (on STDOUT)'
1826 write(*,gf) '--pvt <method>','pivot according to a specific method'
1827 write(*,nf) '--<method> can be one of the following:'
1828- write(*,fm) ' cm: Cuthill-Mckee'
1829- write(*,fm) ' rev-cm: reverse Cuthill-Mckee'
1830- write(*,fm) ' gps: Gibbs-Poole-Stockmeyer'
1831- write(*,fm) ' rev-gps: reverse Gibbs-Poole-Stockmeyer'
1832- write(*,fm) ' pcg: Peripheral connectivity graph'
1833- write(*,fm) ' rev-pcg: reverse Peripheral connectivity graph'
1834- write(*,fm) ' ggps: General Gibbs-Poole-Stockmeyer'
1835- write(*,fm) 'rev-ggps: reverse General Gibbs-Poole-Stockmeyer'
1836+ write(*,fm) 'cm', 'Cuthill-Mckee'
1837+ write(*,fm) 'rev-cm', 'reverse Cuthill-Mckee'
1838+ write(*,fm) 'gps', 'Gibbs-Poole-Stockmeyer'
1839+ write(*,fm) 'rev-gps', 'reverse Gibbs-Poole-Stockmeyer'
1840+ write(*,fm) 'pcg', 'Peripheral connectivity graph'
1841+ write(*,fm) 'rev-pcg', 'reverse Peripheral connectivity graph'
1842+ write(*,fm) 'ggps', 'General Gibbs-Poole-Stockmeyer'
1843+ write(*,fm) 'rev-ggps', 'reverse General Gibbs-Poole-Stockmeyer'
1844 #ifdef SIESTA__METIS
1845- write(*,fm) ' metis: Metis pivoting'
1846+ write(*,fm) 'nodend', 'Metis NodeND pivoting'
1847+ write(*,fm) 'partgraphkway', 'Metis PartGraphKway pivoting'
1848+ write(*,fm) 'partgraphrecursive', 'Metis PartGraphRecursive pivoting'
1849 #endif
1850- write(*,fm) 'scramble: Scramble the sparsity pattern'
1851+ write(*,fm) 'scramble', 'Scramble the sparsity pattern'
1852 write(*,'(a)')
1853 write(*,gf) '--unit-cell|-uc','convert to unit-cell sparsity pattern'
1854 write(*,gf) '--a|-a <i>','use only ith supercell as connectivity graph (in A direction)'
1855
1856=== modified file 'Util/TS/TBtrans/Makefile'
1857--- Util/TS/TBtrans/Makefile 2018-04-07 19:13:42 +0000
1858+++ Util/TS/TBtrans/Makefile 2018-05-04 19:08:45 +0000
1859@@ -445,9 +445,8 @@
1860 denmatlomem.o: alloc.o globalise.o onmod.o precision.o
1861 densematrix.o: alloc.o precision.o
1862 detover.o: alloc.o linpack.o parallel.o parallelsubs.o precision.o
1863-dfscf.o: alloc.o atm_types.o atmfuncs.o atomlist.o listsc.o local_sys.o
1864-dfscf.o: m_spin.o mesh.o meshdscf.o meshphi.o parallel.o parallelsubs.o
1865-dfscf.o: precision.o
1866+dfscf.o: alloc.o atm_types.o atmfuncs.o atomlist.o listsc.o local_sys.o mesh.o
1867+dfscf.o: meshdscf.o meshphi.o parallel.o parallelsubs.o precision.o
1868 dhscf.o: alloc.o atmfuncs.o bsc_xcmod.o cellxc_mod.o delk.o dfscf.o
1869 dhscf.o: doping_uniform.o files.o forhar.o iogrid_netcdf.o local_sys.o
1870 dhscf.o: m_charge_add.o m_efield.o m_hartree_add.o m_iorho.o m_mesh_node.o
1871@@ -655,11 +654,11 @@
1872 m_new_dm.o: class_Fstack_Pair_Geometry_SpData2D.o class_Geometry.o
1873 m_new_dm.o: class_OrbitalDistribution.o class_Pair_Geometry_SpData2D.o
1874 m_new_dm.o: class_SpData2D.o class_Sparsity.o files.o local_sys.o m_energies.o
1875-m_new_dm.o: m_handle_sparse.o m_iodm.o m_mixing.o m_mixing_scf.o m_mpi_utils.o
1876-m_new_dm.o: m_spin.o m_spin.o m_steps.o m_svd.o m_ts_electype.o
1877-m_new_dm.o: m_ts_global_vars.o m_ts_iodm.o m_ts_method.o m_ts_options.o
1878-m_new_dm.o: parallel.o parsing.o precision.o restructSpData2D.o siesta_geom.o
1879-m_new_dm.o: siesta_options.o sparse_matrices.o units.o
1880+m_new_dm.o: m_handle_sparse.o m_iodm.o m_mixing.o m_mixing_scf.o m_spin.o
1881+m_new_dm.o: m_spin.o m_steps.o m_svd.o m_ts_electype.o m_ts_global_vars.o
1882+m_new_dm.o: m_ts_iodm.o m_ts_method.o m_ts_options.o parallel.o parsing.o
1883+m_new_dm.o: precision.o restructSpData2D.o siesta_geom.o siesta_options.o
1884+m_new_dm.o: sparse_matrices.o units.o
1885 m_noccbands.o: alloc.o atmfuncs.o local_sys.o m_spin.o parallel.o precision.o
1886 m_noccbands.o: siesta_geom.o
1887 m_options.o: precision.o
1888@@ -733,13 +732,14 @@
1889 m_ts_contour_eq.o: m_gauss_fermi_17.o m_gauss_fermi_18.o m_gauss_fermi_19.o
1890 m_ts_contour_eq.o: m_gauss_fermi_20.o m_gauss_fermi_22.o m_gauss_fermi_24.o
1891 m_ts_contour_eq.o: m_gauss_fermi_26.o m_gauss_fermi_28.o m_gauss_fermi_30.o
1892-m_ts_contour_eq.o: m_gauss_fermi_inf.o m_gauss_quad.o m_integrate.o m_ts_aux.o
1893-m_ts_contour_eq.o: m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
1894+m_ts_contour_eq.o: m_gauss_fermi_inf.o m_gauss_quad.o m_integrate.o m_io.o
1895+m_ts_contour_eq.o: m_ts_aux.o m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
1896 m_ts_contour_eq.o: m_ts_io_contour.o m_ts_io_ctype.o parallel.o precision.o
1897 m_ts_contour_eq.o: units.o
1898-m_ts_contour_neq.o: m_gauss_quad.o m_integrate.o m_ts_aux.o m_ts_cctype.o
1899-m_ts_contour_neq.o: m_ts_chem_pot.o m_ts_electype.o m_ts_io_contour.o
1900-m_ts_contour_neq.o: m_ts_io_ctype.o parallel.o precision.o units.o
1901+m_ts_contour_neq.o: m_gauss_quad.o m_integrate.o m_io.o m_ts_aux.o
1902+m_ts_contour_neq.o: m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
1903+m_ts_contour_neq.o: m_ts_io_contour.o m_ts_io_ctype.o parallel.o precision.o
1904+m_ts_contour_neq.o: units.o
1905 m_ts_debug.o: class_Sparsity.o class_TriMat.o geom_helper.o parallel.o
1906 m_ts_debug.o: precision.o
1907 m_ts_dm_update.o: class_OrbitalDistribution.o class_SpData1D.o class_SpData2D.o
1908@@ -782,7 +782,7 @@
1909 m_ts_io.o: class_SpData2D.o class_Sparsity.o geom_helper.o local_sys.o m_io_s.o
1910 m_ts_io.o: m_ncdf_io.o m_os.o m_sparse.o parallel.o precision.o
1911 m_ts_io_contour.o: precision.o units.o
1912-m_ts_io_ctype.o: parallel.o precision.o units.o
1913+m_ts_io_ctype.o: m_io.o parallel.o precision.o units.o
1914 m_ts_iodm.o: class_OrbitalDistribution.o class_SpData2D.o class_Sparsity.o
1915 m_ts_iodm.o: m_io_s.o m_os.o parallel.o precision.o
1916 m_ts_kpoints.o: files.o find_kgrid.o kpoint_grid.o local_sys.o
1917@@ -904,7 +904,7 @@
1918 mulliken.o: siesta_cml.o
1919 naefs.o: atmfuncs.o mneighb.o new_matel.o precision.o
1920 new_matel.o: alloc.o errorf.o interpolation.o local_sys.o matel_registry.o
1921-new_matel.o: parallel.o precision.o radfft.o spher_harm.o
1922+new_matel.o: parallel.o precision.o radfft.o siesta_options.o spher_harm.o
1923 nlefsm.o: alloc.o atm_types.o atmfuncs.o atomlist.o chemical.o mneighb.o
1924 nlefsm.o: new_matel.o parallel.o parallelsubs.o precision.o
1925 normalize_dm.o: atomlist.o local_sys.o m_mpi_utils.o m_spin.o parallel.o
1926@@ -990,9 +990,10 @@
1927 save_density_matrix.o: m_ts_global_vars.o m_ts_iodm.o m_ts_options.o
1928 save_density_matrix.o: precision.o siesta_options.o sparse_matrices.o
1929 savepsi.o: alloc.o parallel.o parallelsubs.o precision.o
1930-scfconvergence_test.o: ldau.o ldau_specs.o m_convergence.o m_energies.o
1931-scfconvergence_test.o: m_wallclock.o parallel.o precision.o siesta_cml.o
1932-scfconvergence_test.o: siesta_options.o units.o write_subs.o
1933+scfconvergence_test.o: atomlist.o ldau.o ldau_specs.o m_convergence.o
1934+scfconvergence_test.o: m_energies.o m_spin.o m_wallclock.o parallel.o
1935+scfconvergence_test.o: precision.o siesta_cml.o siesta_geom.o siesta_options.o
1936+scfconvergence_test.o: sparse_matrices.o units.o write_subs.o
1937 schecomm.o: alloc.o
1938 setatomnodes.o: alloc.o local_sys.o parallel.o precision.o spatial.o
1939 setspatial.o: alloc.o parallel.o precision.o spatial.o
1940@@ -1064,10 +1065,10 @@
1941 siesta_move.o: atomlist.o broyden_optim.o cell_broyden_optim.o
1942 siesta_move.o: cell_fire_optim.o dynamics.o fire_optim.o flook_siesta.o ioxv.o
1943 siesta_move.o: local_sys.o m_check_walltime.o m_energies.o m_exp_coord.o
1944-siesta_move.o: m_forces.o m_kinetic.o m_steps.o m_stress.o m_target_stress.o
1945-siesta_move.o: parallel.o siesta_cml.o siesta_dicts.o siesta_geom.o
1946-siesta_move.o: siesta_master.o siesta_options.o units.o write_subs.o
1947-siesta_move.o: zm_broyden_optim.o zm_fire_optim.o zmatrix.o
1948+siesta_move.o: m_forces.o m_kinetic.o m_mpi_utils.o m_steps.o m_stress.o
1949+siesta_move.o: m_target_stress.o parallel.o siesta_cml.o siesta_dicts.o
1950+siesta_move.o: siesta_geom.o siesta_master.o siesta_options.o units.o
1951+siesta_move.o: write_subs.o zm_broyden_optim.o zm_fire_optim.o zmatrix.o
1952 sparse_matrices.o: alloc.o class_Fstack_Pair_Geometry_SpData2D.o
1953 sparse_matrices.o: class_OrbitalDistribution.o class_SpData1D.o
1954 sparse_matrices.o: class_SpData2D.o class_Sparsity.o precision.o
1955@@ -1140,7 +1141,7 @@
1956 zmatrix.o: alloc.o local_sys.o m_cell.o parallel.o precision.o siesta_geom.o
1957 zmatrix.o: units.o
1958 local_sys.o: parallel.o
1959-m_tbt_contour.o: m_gauss_quad.o m_integrate.o m_tbt_save.o m_ts_aux.o
1960+m_tbt_contour.o: m_gauss_quad.o m_integrate.o m_io.o m_tbt_save.o m_ts_aux.o
1961 m_tbt_contour.o: m_ts_cctype.o m_ts_chem_pot.o m_ts_electype.o
1962 m_tbt_contour.o: m_ts_io_contour.o m_ts_io_ctype.o parallel.o precision.o
1963 m_tbt_contour.o: units.o
1964@@ -1177,15 +1178,16 @@
1965 m_tbt_regions.o: class_OrbitalDistribution.o class_Sparsity.o
1966 m_tbt_regions.o: create_Sparsity_SC.o create_Sparsity_Union.o fdf_extra.o
1967 m_tbt_regions.o: files.o geom_helper.o intrinsic_missing.o m_char.o m_pivot.o
1968-m_tbt_regions.o: m_pivot_methods.o m_region.o m_sparsity_handling.o
1969-m_tbt_regions.o: m_ts_debug.o m_ts_electype.o m_ts_method.o m_ts_pivot.o
1970-m_tbt_regions.o: m_ts_sparse.o m_verbosity.o parallel.o precision.o
1971+m_tbt_regions.o: m_pivot_methods.o m_region.o m_sparsity_handling.o m_tbt_dH.o
1972+m_tbt_regions.o: m_tbt_delta.o m_ts_debug.o m_ts_electype.o m_ts_method.o
1973+m_tbt_regions.o: m_ts_pivot.o m_ts_sparse.o m_verbosity.o parallel.o
1974+m_tbt_regions.o: precision.o
1975 m_tbt_save.o: class_OrbitalDistribution.o class_SpData1D.o class_Sparsity.o
1976 m_tbt_save.o: files.o m_interpolate.o m_ncdf_io.o m_os.o m_region.o m_tbt_hs.o
1977 m_tbt_save.o: m_ts_electype.o m_verbosity.o parallel.o precision.o timestamp.o
1978 m_tbt_save.o: units.o
1979 m_tbt_sigma_save.o: m_os.o m_region.o m_tbt_hs.o m_tbt_save.o m_ts_electype.o
1980-m_tbt_sigma_save.o: parallel.o timestamp.o units.o
1981+m_tbt_sigma_save.o: parallel.o precision.o timestamp.o units.o
1982 m_tbt_sparse_helper.o: class_OrbitalDistribution.o class_SpData1D.o
1983 m_tbt_sparse_helper.o: class_Sparsity.o geom_helper.o intrinsic_missing.o
1984 m_tbt_sparse_helper.o: m_region.o m_tbt_kregions.o m_ts_electype.o
1985
1986=== modified file 'Util/TS/TBtrans/m_tbt_contour.F90'
1987--- Util/TS/TBtrans/m_tbt_contour.F90 2018-03-22 10:43:42 +0000
1988+++ Util/TS/TBtrans/m_tbt_contour.F90 2018-05-04 19:08:45 +0000
1989@@ -239,15 +239,19 @@
1990 type(ts_cw), intent(inout) :: c
1991 real(dp), intent(in) :: Eta
1992
1993- if ( leqi(c%c_io%part,'line') ) then
1994-
1995- call contour_line(c,Eta)
1996-
1997+ if ( leqi(c%c_io%part,'user') ) then
1998+
1999+ call contour_file(c,Eta)
2000+
2001+ else if ( leqi(c%c_io%part,'line') ) then
2002+
2003+ call contour_line(c,Eta)
2004+
2005 else
2006-
2007- call neq_die('Unrecognized contour type for &
2008- &tbtrans, MUST be a line part.')
2009-
2010+
2011+ call neq_die('Unrecognized contour type for &
2012+ &tbtrans, MUST be a line part.')
2013+
2014 end if
2015
2016 end subroutine setup_tbt_contour
2017@@ -308,7 +312,14 @@
2018 end if
2019
2020 call TanhSinh_Exact(c%c_io%N,ce,cw,a,b, p=tmp)
2021-
2022+
2023+ case ( CC_USER )
2024+
2025+ call contour_file(c,Eta)
2026+
2027+ deallocate(ce, cw)
2028+ return
2029+
2030 case default
2031
2032 call die('Could not determine the line-integral')
2033@@ -322,6 +333,108 @@
2034
2035 end subroutine contour_line
2036
2037+ ! This routine will read the contour points from a file
2038+ subroutine contour_file(c,Eta)
2039+ use m_io, only: io_assign, io_close
2040+ use fdf, only: fdf_convfac
2041+
2042+ type(ts_cw), intent(inout) :: c
2043+ ! The lifting into the complex plane
2044+ real(dp), intent(in) :: Eta
2045+
2046+ integer :: iu, iostat, ne
2047+ logical :: exist
2048+ complex(dp) :: E , W
2049+ real(dp) :: rE, iE, rW, iW, conv
2050+ character(len=512) :: file, line
2051+ character(len=16) :: unit
2052+
2053+ ! The contour type contains the file name in:
2054+ ! c%c_io%cN (weirdly enough)
2055+ file = c%c_io%cN
2056+
2057+ call io_assign(iu)
2058+
2059+ ! Open the contour file
2060+ inquire(file=trim(file), exist=exist)
2061+ if ( .not. exist ) then
2062+ call die('The file: '//trim(file)//' could not be found to read contour points!')
2063+ end if
2064+
2065+ ! Open the file
2066+ open(iu, file=trim(file), form='formatted', status='old')
2067+
2068+ ne = 0
2069+ ! The default unit is eV.
2070+ ! On every line an optional unit-specificer may be used to specify the
2071+ ! subsequent lines units (until another unit is specified)
2072+ conv = fdf_convfac('eV', 'Ry')
2073+ do
2074+ ! Now we have the line
2075+ read(iu, '(a)', iostat=iostat) line
2076+ if ( iostat /= 0 ) exit
2077+ if ( len_trim(line) == 0 ) cycle
2078+ line = trim(adjustl(line))
2079+ if ( line(1:1) == '#' ) cycle
2080+
2081+ ! We have a line with energy and weight
2082+ ne = ne + 1
2083+ ! There are three optional ways of reading this
2084+ ! 1. ReE ImE, ReW ImW [unit]
2085+ read(line, *, iostat=iostat) rE, iE, rW, iW, unit
2086+ if ( iostat == 0 ) then
2087+ conv = fdf_convfac(unit, 'Ry')
2088+ else
2089+ read(line, *, iostat=iostat) rE, iE, rW, iW
2090+ end if
2091+ if ( iostat == 0 ) then
2092+ c%c(ne) = dcmplx(rE,iE) * conv
2093+ c%w(ne,1) = dcmplx(rW,iW) * conv
2094+ cycle
2095+ end if
2096+
2097+ ! 2. ReE ImE, ReW [unit]
2098+ iW = 0._dp
2099+ read(line, *, iostat=iostat) rE, iE, rW, unit
2100+ if ( iostat == 0 ) then
2101+ conv = fdf_convfac(unit, 'Ry')
2102+ else
2103+ read(line, *, iostat=iostat) rE, iE, rW
2104+ end if
2105+ if ( iostat == 0 ) then
2106+ c%c(ne) = dcmplx(rE,iE) * conv
2107+ c%w(ne,1) = dcmplx(rW,iW) * conv
2108+ cycle
2109+ end if
2110+
2111+ ! 3. ReE , ReW [unit]
2112+ iE = Eta
2113+ iW = 0._dp
2114+ read(line, *, iostat=iostat) rE, rW, unit
2115+ if ( iostat == 0 ) then
2116+ conv = fdf_convfac(unit, 'Ry')
2117+ else
2118+ read(line, *, iostat=iostat) rE, rW
2119+ end if
2120+ if ( iostat == 0 ) then
2121+ c%c(ne) = dcmplx(rE * conv,iE)
2122+ c%w(ne,1) = dcmplx(rW,iW) * conv
2123+ cycle
2124+ end if
2125+
2126+ call die('Contour file: '//trim(file)//' is not formatted correctly. &
2127+ &Please read the documentation!')
2128+
2129+ end do
2130+
2131+ call io_close(iu)
2132+
2133+ if ( c%c_io%N /= ne ) then
2134+ call die('Error in reading the contour points from file: '//trim(file))
2135+ end if
2136+
2137+ end subroutine contour_file
2138+
2139 function TBT_E(id,step) result(c)
2140 integer, intent(in) :: id
2141 integer, intent(in), optional :: step
2142
2143=== modified file 'Util/TS/TBtrans/m_tbt_options.F90'
2144--- Util/TS/TBtrans/m_tbt_options.F90 2018-03-22 10:43:42 +0000
2145+++ Util/TS/TBtrans/m_tbt_options.F90 2018-05-04 19:08:45 +0000
2146@@ -602,6 +602,26 @@
2147 &apply.','Set TBT.DOS.A T to calculate orbital currents.'
2148 end if
2149
2150+ ! Options for density-matrix calculations
2151+ ltmp = fdf_get('TBT.DM.Gf', .false.)
2152+ if ( ltmp .and. ('DOS-Gf'.in.save_DATA)) then
2153+ save_DATA = save_DATA // ('DM-Gf'.kv.1)
2154+ else if ( ltmp .and. IONode ) then
2155+ write(*,'(2(/,a))')'WARNING: Will not calculate the density matrix (Gf), &
2156+ &the Green function DOS needs to be calculated for this to &
2157+ &apply.','Set TBT.DOS.Gf T to calculate density matrix (Gf).'
2158+ end if
2159+
2160+ ltmp = fdf_get('TBT.DM.A', .false.)
2161+ if ( ltmp .and. ('DOS-A'.in.save_DATA)) then
2162+ save_DATA = save_DATA // ('DM-A'.kv.1)
2163+ else if ( ltmp .and. IONode ) then
2164+ write(*,'(2(/,a))')'WARNING: Will not calculate the density matrix (A), &
2165+ &the spectral function DOS needs to be calculated for this to &
2166+ &apply.','Set TBT.DOS.A T to calculate density matrix (A).'
2167+ end if
2168+
2169+
2170 ! Options for COOP and COHP curves.
2171 ! These are orbital (energy) populations that can be used to determine the
2172 ! bonding nature of the material.
2173@@ -619,7 +639,7 @@
2174 save_DATA = save_DATA // ('COOP-A'.kv.1)
2175 else if ( ltmp .and. IONode ) then
2176 write(*,'(2(/,a))')'WARNING: Will not calculate the COOP (A) curve, &
2177- &the Green function DOS needs to be calculated for this to &
2178+ &the spectral function DOS needs to be calculated for this to &
2179 &apply.','Set TBT.DOS.A T to calculate COOP (A) curves.'
2180 end if
2181
2182@@ -637,7 +657,7 @@
2183 save_DATA = save_DATA // ('COHP-A'.kv.1)
2184 else if ( ltmp .and. IONode ) then
2185 write(*,'(2(/,a))')'WARNING: Will not calculate the COHP (A) curve, &
2186- &the Green function DOS needs to be calculated for this to &
2187+ &the spectral function DOS needs to be calculated for this to &
2188 &apply.','Set TBT.DOS.A T to calculate COHP (A) curves.'
2189 end if
2190
2191@@ -749,6 +769,10 @@
2192 end if
2193 write(*,f1) 'Saving bond currents (orb-orb)',('orb-current'.in.save_DATA)
2194
2195+ ! DM
2196+ write(*,f1) 'Saving DM from Green function',('DM-Gf'.in.save_DATA)
2197+ write(*,f1) 'Saving DM from spectral functions',('DM-A'.in.save_DATA)
2198+
2199 ! COOP/COHP curves
2200 write(*,f1) 'Saving COOP from Green function',('COOP-Gf'.in.save_DATA)
2201 write(*,f1) 'Saving COOP from spectral functions',('COOP-A'.in.save_DATA)
2202@@ -874,7 +898,7 @@
2203 has = has .or. ('COOP-A' .in. save_DATA)
2204 has = has .or. ('COHP-Gf' .in. save_DATA)
2205 has = has .or. ('COHP-A' .in. save_DATA)
2206- if ( IONode .and. ltmp .and. has) then
2207+ if ( IONode .and. ltmp .and. has ) then
2208 write(*,'(a,/,a)') 'WARNING: k-averaging COOP/COHP with &
2209 &time-reversal symmetry will not reproduce','the correct &
2210 &populations. Set TBT.Symmetry.TimeReversal F'
2211
2212=== modified file 'Util/TS/TBtrans/m_tbt_proj.F90'
2213--- Util/TS/TBtrans/m_tbt_proj.F90 2018-03-22 10:43:42 +0000
2214+++ Util/TS/TBtrans/m_tbt_proj.F90 2018-05-04 19:08:45 +0000
2215@@ -1306,7 +1306,7 @@
2216
2217 ! Initialize the TBT.Proj.nc file
2218 subroutine init_proj_save( fname, TSHS , r, btd, ispin, N_Elec, Elecs, &
2219- nkpt, kpt, wkpt, NE , a_Dev, a_Buf, sp_dev_sc, save_DATA )
2220+ nkpt, kpt, wkpt, NE , Eta, a_Dev, a_Buf, sp_dev_sc, save_DATA )
2221
2222 use parallel, only : Node, Nodes, IONode
2223 use units, only: eV
2224@@ -1341,6 +1341,7 @@
2225 integer, intent(in) :: N_Elec
2226 type(Elec), intent(in) :: Elecs(N_Elec)
2227 integer, intent(in) :: nkpt, NE
2228+ real(dp), intent(in) :: Eta
2229 real(dp), intent(in) :: kpt(3,nkpt), wkpt(nkpt)
2230 type(tRgn), intent(in) :: a_Dev
2231 type(tRgn), intent(in) :: a_Buf
2232@@ -1684,8 +1685,11 @@
2233 #else
2234 dic = dic//('info'.kv.'Energy')//('unit'.kv.'Ry')
2235 #endif
2236- call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), &
2237- atts = dic)
2238+ call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), atts = dic)
2239+
2240+ dic = dic//('info'.kv.'Imaginary part for device')
2241+ call ncdf_def_var(ncdf,'eta',NF90_DOUBLE,(/'one'/), atts = dic)
2242+
2243 call delete(dic)
2244
2245 call ncdf_put_var(ncdf,'nsc',TSHS%nsc)
2246@@ -1716,6 +1720,8 @@
2247 call ncdf_put_var(ncdf,'wkpt',wkpt)
2248 deallocate(rv)
2249
2250+ call ncdf_put_var(ncdf,'eta',Eta)
2251+
2252 if ( 'proj-orb-current' .in. save_DATA ) then
2253
2254 ! In case we need to save the device sparsity pattern
2255
2256=== modified file 'Util/TS/TBtrans/m_tbt_regions.F90'
2257--- Util/TS/TBtrans/m_tbt_regions.F90 2018-04-07 18:57:43 +0000
2258+++ Util/TS/TBtrans/m_tbt_regions.F90 2018-05-04 19:08:45 +0000
2259@@ -773,7 +773,11 @@
2260 #ifdef MPI
2261 use mpi_siesta, only : MPI_Comm_Self
2262 #endif
2263- use m_sparsity_handling, only : Sp_retain_region, Sp_sort
2264+ use m_sparsity_handling, only : Sp_retain_region, Sp_sort, Sp_union
2265+#ifdef NCDF_4
2266+ use m_tbt_delta, only: read_delta_Sp
2267+ use m_tbt_dH, only: use_dH, dH
2268+#endif
2269
2270 type(Sparsity), intent(inout) :: sp
2271 type(dict), intent(in) :: save_DATA
2272@@ -781,6 +785,7 @@
2273 type(OrbitalDistribution) :: fdit
2274
2275 integer :: no_u
2276+ type(Sparsity) :: sp_dH
2277 #endif
2278
2279 ! Make sure to initialize the device region
2280@@ -789,6 +794,7 @@
2281 #ifdef NCDF_4
2282 if ( ('orb-current' .in. save_DATA) .or. &
2283 ('proj-orb-current' .in. save_DATA) .or. &
2284+ ('DM-Gf' .in. save_DATA) .or. ('DM-A' .in. save_DATA) .or. &
2285 ('COOP-Gf' .in. save_DATA) .or. ('COHP-Gf' .in. save_DATA) .or. &
2286 ('COOP-A' .in. save_DATA) .or. ('COHP-A' .in. save_DATA) ) then
2287
2288@@ -798,8 +804,15 @@
2289 #else
2290 call newDistribution(no_u,-1 ,fdit,name='TBT-fake dist')
2291 #endif
2292-
2293 call Sp_retain_region(fdit,sp,r_oDev,sp_dev_sc)
2294+ ! Note that the delta-Sigma is not necessary because
2295+ ! the self-energy does not add to bond-currents, etc.
2296+ if ( use_dH ) then
2297+ call read_delta_Sp(dH,no_u,sp_dH)
2298+ call Sp_retain_region(fdit,sp_dH,r_oDev,sp_dH)
2299+ call Sp_union(fdit,sp_dev_sc,sp_dH,sp_dev_sc)
2300+ call delete(sp_dH)
2301+ end if
2302 call Sp_sort(sp_dev_sc)
2303 call delete(fdit)
2304
2305
2306=== modified file 'Util/TS/TBtrans/m_tbt_save.F90'
2307--- Util/TS/TBtrans/m_tbt_save.F90 2018-04-09 12:39:44 +0000
2308+++ Util/TS/TBtrans/m_tbt_save.F90 2018-05-04 19:08:45 +0000
2309@@ -311,7 +311,7 @@
2310
2311 subroutine init_cdf_save(fname,TSHS,r,btd,ispin, &
2312 N_Elec, Elecs, rEl, btd_El, &
2313- nkpt, kpt, wkpt, NE, &
2314+ nkpt, kpt, wkpt, NE, Eta, &
2315 a_Dev, a_Buf, sp_dev_sc, &
2316 save_DATA )
2317
2318@@ -349,6 +349,7 @@
2319 integer, intent(in) :: nkpt
2320 real(dp), intent(in), target :: kpt(3,nkpt), wkpt(nkpt)
2321 integer, intent(in) :: NE
2322+ real(dp), intent(in) :: Eta
2323 type(tRgn), intent(in) :: a_Dev
2324 ! In case the system has some buffer atoms.
2325 type(tRgn), intent(in) :: a_Buf
2326@@ -362,7 +363,7 @@
2327 type(dict) :: dic
2328 logical :: exist, sme, isGamma
2329 integer :: iEl, jEl, i, nnzs_dev, N_eigen
2330- integer :: prec_DOS, prec_T, prec_Teig, prec_J, prec_COOP
2331+ integer :: prec_DOS, prec_T, prec_Teig, prec_J, prec_COOP, prec_DM
2332 type(OrbitalDistribution) :: fdit
2333 real(dp) :: mem
2334 character(len=2) :: unit
2335@@ -383,6 +384,7 @@
2336 call tbt_cdf_precision('T.Eig','single',prec_Teig)
2337 call tbt_cdf_precision('Current','single',prec_J)
2338 call tbt_cdf_precision('COOP','single',prec_COOP)
2339+ call tbt_cdf_precision('DM','single',prec_DM)
2340
2341 isGamma = all(TSHS%nsc(:) == 1)
2342
2343@@ -579,6 +581,7 @@
2344 dic = dic // ('info'.kv.'Blocks in BTD for the pivot table')
2345 call ncdf_def_var(ncdf,'btd',NF90_INT,(/'n_btd'/), &
2346 atts = dic)
2347+ mem = mem + calc_mem(NF90_INT, btd%n)
2348
2349 dic = dic // ('info'.kv.'Index of device atoms')
2350 call ncdf_def_var(ncdf,'a_dev',NF90_INT,(/'na_d'/), &
2351@@ -613,11 +616,15 @@
2352 #else
2353 dic = dic//('info'.kv.'Energy')//('unit'.kv.'Ry')
2354 #endif
2355- call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), &
2356- atts = dic, chunks = (/1/) )
2357- call delete(dic)
2358+ call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), atts = dic)
2359 mem = mem + calc_mem(NF90_DOUBLE, NE)
2360
2361+ dic = dic//('info'.kv.'Imaginary part for device')
2362+ call ncdf_def_var(ncdf,'eta',NF90_DOUBLE,(/'one'/), atts = dic)
2363+
2364+ ! Clean-up dictionary
2365+ call delete(dic)
2366+
2367 call ncdf_put_var(ncdf,'nsc',TSHS%nsc)
2368 call ncdf_put_var(ncdf,'isc_off',TSHS%isc_off)
2369 call ncdf_put_var(ncdf,'pivot',r%r)
2370@@ -646,11 +653,15 @@
2371 call ncdf_put_var(ncdf,'wkpt',wkpt)
2372 deallocate(r2)
2373
2374+ call ncdf_put_var(ncdf,'eta',Eta)
2375+
2376 sme = 'orb-current' .in. save_DATA
2377 sme = sme .or. ('COOP-Gf' .in. save_DATA)
2378 sme = sme .or. ('COOP-A' .in. save_DATA)
2379 sme = sme .or. ('COHP-Gf' .in. save_DATA)
2380 sme = sme .or. ('COHP-A' .in. save_DATA)
2381+ sme = sme .or. ('DM-Gf' .in. save_DATA)
2382+ sme = sme .or. ('DM-A' .in. save_DATA)
2383 if ( sme ) then
2384
2385 ! In case we need to save the device sparsity pattern
2386@@ -683,6 +694,12 @@
2387
2388 end if
2389
2390+ if ( 'DM-Gf' .in. save_DATA ) then
2391+ dic = dic // ('info'.kv.'Green function density matrix')
2392+ call ncdf_def_var(ncdf,'DM',prec_DM,(/'nnzs','ne ','nkpt'/), &
2393+ atts = dic , chunks = (/nnzs_dev/) , compress_lvl=cmp_lvl)
2394+ mem = mem + calc_mem(prec_DM, nnzs_dev, NE, nkpt)
2395+ end if
2396 if ( 'COOP-Gf' .in. save_DATA ) then
2397 dic = dic // ('info'.kv.'Crystal orbital overlap population')//('unit'.kv.'1/Ry')
2398 call ncdf_def_var(ncdf,'COOP',prec_COOP,(/'nnzs','ne ','nkpt'/), &
2399@@ -747,15 +764,18 @@
2400 dic = ('info'.kv.'Last orbitals of the equivalent atom')
2401 call ncdf_def_var(grp,'lasto',NF90_INT,(/'na_u'/), &
2402 atts = dic)
2403+ mem = mem + calc_mem(NF90_INT, Elecs(iEl)%na_u)
2404+
2405 dic = dic//('info'.kv.'Bulk transmission')
2406 call ncdf_def_var(grp,'T',prec_T,(/'ne ','nkpt'/), &
2407- atts = dic)
2408+ atts = dic)
2409 mem = mem + calc_mem(prec_T, NE, nkpt)
2410
2411 dic = dic//('info'.kv.'Unit cell')
2412 dic = dic//('unit'.kv.'Bohr')
2413 call ncdf_def_var(grp,'cell',NF90_DOUBLE,(/'xyz','xyz'/), &
2414 atts = dic)
2415+
2416 dic = dic//('info'.kv.'Atomic coordinates')
2417 call ncdf_def_var(grp,'xa',NF90_DOUBLE,(/'xyz ','na_u'/), &
2418 atts = dic , chunks = (/3, Elecs(iEl)%na_u/) )
2419@@ -773,7 +793,7 @@
2420 mem = mem + calc_mem(prec_DOS, Elecs(iEl)%no_u, NE, nkpt)
2421
2422 end if
2423-
2424+ call delete(dic)
2425
2426 ! Now we will only add information that is calculated
2427 if ( iEl == N_Elec ) then
2428@@ -782,6 +802,12 @@
2429 ('T-all'.nin. save_DATA) ) cycle
2430 end if
2431
2432+ if ( 'DM-A' .in. save_DATA ) then
2433+ dic = dic // ('info'.kv.'Spectral function density matrix')
2434+ call ncdf_def_var(grp,'DM',prec_DM,(/'nnzs','ne ','nkpt'/), &
2435+ atts = dic , chunks = (/nnzs_dev/) , compress_lvl=cmp_lvl)
2436+ mem = mem + calc_mem(prec_DM, nnzs_dev, NE, nkpt)
2437+ end if
2438
2439 if ( 'DOS-A' .in. save_DATA ) then
2440 dic = dic//('info'.kv.'Spectral function density of states')// &
2441@@ -1162,7 +1188,7 @@
2442 #endif
2443
2444 #ifdef TBTRANS_TIMING
2445- call timer('cdf-w-DTJ',1)
2446+ call timer('cdf-w-DOS-T',1)
2447 #endif
2448
2449 NDOS = size(DOS,dim=1)
2450@@ -1308,7 +1334,7 @@
2451 #endif
2452
2453 #ifdef TBTRANS_TIMING
2454- call timer('cdf-w-DTJ',2)
2455+ call timer('cdf-w-DOS-T',2)
2456 #endif
2457
2458 end subroutine state_cdf_save
2459
2460=== modified file 'Util/TS/TBtrans/m_tbt_sigma_save.F90'
2461--- Util/TS/TBtrans/m_tbt_sigma_save.F90 2018-04-09 12:39:44 +0000
2462+++ Util/TS/TBtrans/m_tbt_sigma_save.F90 2018-05-04 19:08:45 +0000
2463@@ -139,7 +139,7 @@
2464
2465 ! Save the self-energies of the electrodes and
2466 subroutine init_Sigma_save(fname, TSHS, r, btd, ispin, N_Elec, Elecs, &
2467- nkpt, kpt, wkpt, NE, &
2468+ nkpt, kpt, wkpt, NE, Eta, &
2469 a_Dev, a_Buf)
2470
2471 use parallel, only : IONode
2472@@ -168,6 +168,8 @@
2473 integer, intent(in) :: nkpt
2474 real(dp), intent(in) :: kpt(3,nkpt), wkpt(nkpt)
2475 integer, intent(in) :: NE
2476+ real(dp), intent(in) :: Eta
2477+
2478 ! Device atoms
2479 type(tRgn), intent(in) :: a_Dev
2480 ! Buffer atoms
2481@@ -379,8 +381,11 @@
2482 #else
2483 dic = dic//('info'.kv.'Energy')//('unit'.kv.'Ry')
2484 #endif
2485- call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), &
2486- atts = dic)
2487+ call ncdf_def_var(ncdf,'E',NF90_DOUBLE,(/'ne'/), atts = dic)
2488+
2489+ dic = dic//('info'.kv.'Imaginary part for device')
2490+ call ncdf_def_var(ncdf,'eta',NF90_DOUBLE,(/'one'/), atts = dic)
2491+
2492 call delete(dic)
2493
2494 call ncdf_put_var(ncdf,'pivot',r%r)
2495@@ -412,6 +417,8 @@
2496 deallocate(r2)
2497 mem = mem + calc_mem(NF90_DOUBLE, 4, nkpt)
2498
2499+ call ncdf_put_var(ncdf,'eta',Eta)
2500+
2501 do iEl = 1 , N_Elec
2502
2503 call ncdf_def_grp(ncdf,trim(Elecs(iEl)%name),grp)
2504
2505=== modified file 'Util/TS/TBtrans/m_tbt_tri_scat.F90'
2506--- Util/TS/TBtrans/m_tbt_tri_scat.F90 2017-12-07 21:13:32 +0000
2507+++ Util/TS/TBtrans/m_tbt_tri_scat.F90 2018-05-04 19:08:45 +0000
2508@@ -47,6 +47,7 @@
2509 public :: GF_COHP_add_dH, A_COHP_add_dH
2510 public :: orb_current
2511 public :: orb_current_add_dH
2512+ public :: GF_DM, A_DM
2513 #endif
2514
2515 ! Used for BLAS calls (local variables)
2516@@ -68,18 +69,19 @@
2517 ! This routine utilizes the sparse matrix as a loop, instead of looping
2518 ! all BTD matrix elements.
2519 ! This turns out to be much faster for (at least tight-binding calculations).
2520- subroutine GF_DOS(r,Gf_tri,work_tri,S_1D,pvt,DOS)
2521+ subroutine GF_DOS(r,Gfd_tri,Gfo_tri,S_1D,pvt,DOS)
2522 use class_Sparsity
2523 use class_zSpData1D
2524
2525 type(tRgn), intent(in) :: r
2526- type(zTriMat), intent(inout) :: Gf_tri, work_tri
2527+ type(zTriMat), intent(inout) :: Gfd_tri, Gfo_tri
2528 type(zSpData1D), intent(inout) :: S_1D ! (transposed S(k))
2529 type(tRgn), intent(in) :: pvt
2530 real(dp), intent(out) :: DOS(r%n)
2531
2532 type(Sparsity), pointer :: sp
2533 complex(dp), pointer :: S(:)
2534+ complex(dp), pointer :: Gfd(:), Gfo(:)
2535 complex(dp) :: GfGfd
2536 integer, pointer :: ncol(:), l_ptr(:), l_col(:)
2537 integer :: np, n, no_o, no_i
2538@@ -87,29 +89,29 @@
2539 real(dp) :: lDOS
2540
2541 #ifdef TBTRANS_TIMING
2542- call timer('GF-DOS',1)
2543+ call timer('Gf-DOS',1)
2544 #endif
2545
2546- np = parts(Gf_tri)
2547+ np = parts(Gfd_tri)
2548
2549 ! First calculate all off-diagonal green-function elements
2550- no_o = nrows_g(Gf_tri,1)
2551- no_i = nrows_g(Gf_tri,2)
2552+ no_o = nrows_g(Gfd_tri,1)
2553+ no_i = nrows_g(Gfd_tri,2)
2554 call calc(2,1)
2555 do n = 2, np - 1
2556- no_o = nrows_g(Gf_tri,n)
2557- no_i = nrows_g(Gf_tri,n + 1)
2558+ no_o = nrows_g(Gfd_tri,n)
2559+ no_i = nrows_g(Gfd_tri,n + 1)
2560 call calc(n+1,n)
2561- no_i = nrows_g(Gf_tri,n - 1)
2562+ no_i = nrows_g(Gfd_tri,n - 1)
2563 call calc(n-1,n)
2564 end do
2565- no_o = nrows_g(Gf_tri,np)
2566- no_i = nrows_g(Gf_tri,np-1)
2567+ no_o = nrows_g(Gfd_tri,np)
2568+ no_i = nrows_g(Gfd_tri,np-1)
2569 call calc(np-1,np)
2570
2571 ! At this point we have calculated all Green function matrices
2572- ! All diagonal elements are in Gf_tri,
2573- ! all off-diagonal elements are in work_tri
2574+ ! All diagonal elements are in Gfd_tri,
2575+ ! all off-diagonal elements are in Gfo_tri
2576
2577 ! The DOS per orbital is calculated like this (.=matrix multiplication):
2578 ! DOS(io) = - Im[ (Gf-Gf^\dagger) . S ](io,io) / Pi
2579@@ -126,6 +128,9 @@
2580 S => val(S_1D)
2581 call attach(sp,n_col=ncol,list_ptr=l_ptr,list_col=l_col)
2582
2583+ Gfd => val(Gfd_tri)
2584+ Gfo => val(Gfo_tri)
2585+
2586 !$OMP parallel do default(shared), private(br,io,lDOS,ind,bc,GfGfd)
2587 do br = 1, r%n
2588 io = r%r(br)
2589@@ -135,7 +140,7 @@
2590 do ind = l_ptr(io) + 1, l_ptr(io) + ncol(io)
2591 bc = pvt%r(l_col(ind))
2592 if ( bc > 0 ) then
2593- call index_GfGfd(br, bc, GfGfd)
2594+ call calc_GfGfd(br, bc, GfGfd)
2595 lDOS = lDOS + dimag( GfGfd * S(ind) )
2596 end if
2597 end do
2598@@ -146,7 +151,7 @@
2599 !$OMP end parallel do
2600
2601 #ifdef TBTRANS_TIMING
2602- call timer('GF-DOS',2)
2603+ call timer('Gf-DOS',2)
2604 #endif
2605
2606 contains
2607@@ -155,9 +160,9 @@
2608 integer, intent(in) :: m,n
2609 complex(dp), pointer :: Gf(:), Mnn(:), XY(:)
2610
2611- XY => val(Gf_tri,m,n)
2612- Mnn => val(Gf_tri,n,n)
2613- Gf => val(work_tri,m,n)
2614+ XY => val(Gfd_tri,m,n)
2615+ Mnn => val(Gfd_tri,n,n)
2616+ Gf => val(Gfo_tri,m,n)
2617
2618 ! We need to calculate the
2619 ! Mnm1n/Mnp1n Green's function
2620@@ -171,29 +176,26 @@
2621
2622 end subroutine calc
2623
2624- subroutine index_GfGfd(br, bc, G)
2625+ subroutine calc_GfGfd(br, bc, G)
2626 integer, intent(in) :: br, bc
2627- complex(dp), intent(out) :: G
2628- complex(dp), pointer :: Gf(:)
2629- integer :: p_r, i_r, p_c, i_c
2630-
2631- call part_index(work_tri, br, p_r, i_r)
2632- call part_index(work_tri, bc, p_c, i_c)
2633-
2634+ complex(dp), intent(inout) :: G
2635+ integer :: p_r, i_r, p_c, i_c, i
2636+
2637+ call part_index(Gfo_tri, br, p_r, i_r)
2638+ call part_index(Gfo_tri, bc, p_c, i_c)
2639+
2640 if ( p_r == p_c ) then
2641- Gf => val(Gf_tri, p_r, p_c)
2642+ i = index_block(Gfo_tri, p_r, p_c)
2643+ G = Gfd(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2644+ G = G - conjg(Gfd(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2645 else
2646- Gf => val(work_tri, p_r, p_c)
2647- end if
2648- G = Gf(i_r + (i_c-1) * work_tri%data%tri_nrows(p_r))
2649-
2650- ! Immediate subtract G^\dagger element
2651- if ( p_r /= p_c ) then
2652- Gf => val(work_tri, p_c, p_r)
2653- end if
2654- G = G - conjg(Gf(i_c + (i_r-1) * work_tri%data%tri_nrows(p_c)))
2655-
2656- end subroutine index_GfGfd
2657+ i = index_block(Gfo_tri, p_r, p_c)
2658+ G = Gfo(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2659+ i = index_block(Gfo_tri, p_c, p_r)
2660+ G = G - conjg(Gfo(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2661+ end if
2662+
2663+ end subroutine calc_GfGfd
2664
2665 end subroutine GF_DOS
2666
2667@@ -267,7 +269,7 @@
2668 ! This routine utilizes the sparse matrix as a loop, instead of looping
2669 ! all BTD matrix elements.
2670 ! This turns out to be much faster for (at least tight-binding calculations).
2671- subroutine GF_COP(r,Gfd_tri,Gfo_tri,pvt,sp,M,sc_off,k,COP)
2672+ subroutine GF_COP(r,Gfd_tri,Gfo_tri,pvt,sp,M,sc_off,k,ph,COP)
2673 use class_Sparsity
2674 use class_dSpData1D
2675 use intrinsic_missing, only : SFIND
2676@@ -280,18 +282,19 @@
2677 real(dp), intent(in) :: M(:) ! S for COOP, H for COHP
2678 real(dp), intent(in) :: sc_off(:,:)
2679 real(dp), intent(in) :: k(3)
2680+ complex(dp), intent(inout) :: ph(0:)
2681 type(dSpData1D), intent(inout) :: COP ! COOP or COHP
2682
2683 type(Sparsity), pointer :: c_sp
2684 real(dp), pointer :: C(:)
2685+ complex(dp), pointer :: Gfd(:), Gfo(:)
2686 complex(dp) :: GfGfd
2687- complex(dp), allocatable :: ph(:)
2688 integer, pointer :: ncol(:), l_ptr(:), l_col(:)
2689 integer, pointer :: cncol(:), cptr(:), ccol(:), c_col(:)
2690 integer :: no_u, br, io, ind, iind, bc
2691
2692 #ifdef TBTRANS_TIMING
2693- call timer('GF-COP',1)
2694+ call timer('Gf-COP',1)
2695 #endif
2696
2697 #ifdef TBT_PHONON
2698@@ -317,7 +320,6 @@
2699 ! Since we have to do Gf.S we simply
2700 ! create S(-k) (which is S^T)
2701 ! and thus get the correct values.
2702- allocate( ph(0:size(sc_off,dim=2)-1) )
2703 do io = 1 , size(sc_off, dim=2)
2704 ph(io-1) = cdexp(dcmplx(0._dp, - &
2705 k(1) * sc_off(1,io) - &
2706@@ -331,6 +333,9 @@
2707 C => val(COP)
2708 call attach(c_sp, n_col=cncol, list_ptr=cptr, list_col=ccol)
2709
2710+ Gfd => val(Gfd_tri)
2711+ Gfo => val(Gfo_tri)
2712+
2713 !$OMP parallel default(shared), private(br,io,c_col,ind,iind,bc,GfGfd)
2714
2715 !$OMP workshare
2716@@ -357,7 +362,7 @@
2717
2718 ! COOP(iind) = - Im[ (G(io,jo) - G^\dagger(io,jo)) * S(jo,io) ] / 2Pi
2719 bc = pvt%r(ucorb(l_col(ind),no_u)) ! pivoted orbital index in tri-diagonal matrix
2720- call index_GfGfd(br, bc, GfGfd)
2721+ call calc_GfGfd(br, bc, GfGfd)
2722
2723 C(iind) = -aimag( GfGfd * M(ind) * ph( (l_col(ind)-1)/no_u ))
2724
2725@@ -367,42 +372,36 @@
2726 !$OMP end do
2727 !$OMP end parallel
2728
2729- ! Clean-up phases
2730- deallocate(ph)
2731-
2732 #ifdef TBTRANS_TIMING
2733- call timer('GF-COP',2)
2734+ call timer('Gf-COP',2)
2735 #endif
2736
2737 contains
2738
2739- subroutine index_GfGfd(br, bc, G)
2740+ subroutine calc_GfGfd(br, bc, G)
2741 integer, intent(in) :: br, bc
2742- complex(dp), intent(out) :: G
2743- complex(dp), pointer :: Gf(:)
2744- integer :: p_r, i_r, p_c, i_c
2745-
2746+ complex(dp), intent(inout) :: G
2747+ integer :: p_r, i_r, p_c, i_c, i
2748+
2749 call part_index(Gfo_tri, br, p_r, i_r)
2750 call part_index(Gfo_tri, bc, p_c, i_c)
2751-
2752+
2753 if ( p_r == p_c ) then
2754- Gf => val(Gfd_tri, p_r, p_c)
2755+ i = index_block(Gfo_tri, p_r, p_c)
2756+ G = Gfd(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2757+ G = G - conjg(Gfd(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2758 else
2759- Gf => val(Gfo_tri, p_r, p_c)
2760- end if
2761- G = Gf(i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2762-
2763- ! Immediate subtract G^\dagger element
2764- if ( p_r /= p_c ) then
2765- Gf => val(Gfo_tri, p_c, p_r)
2766- end if
2767- G = G - conjg(Gf(i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2768-
2769- end subroutine index_GfGfd
2770+ i = index_block(Gfo_tri, p_r, p_c)
2771+ G = Gfo(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2772+ i = index_block(Gfo_tri, p_c, p_r)
2773+ G = G - conjg(Gfo(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2774+ end if
2775+
2776+ end subroutine calc_GfGfd
2777
2778 end subroutine GF_COP
2779
2780- subroutine Gf_COHP_add_dH(dH_1D,sc_off,k,Gfd_tri,Gfo_tri,r,COHP,pvt)
2781+ subroutine Gf_COHP_add_dH(dH_1D,sc_off,k,ph,Gfd_tri,Gfo_tri,r,COHP,pvt)
2782
2783 use class_Sparsity
2784 use class_zSpData1D
2785@@ -412,6 +411,7 @@
2786
2787 type(zSpData1D), intent(in) :: dH_1D
2788 real(dp), intent(in) :: sc_off(:,:), k(3)
2789+ complex(dp), intent(inout) :: ph(0:)
2790 type(zTriMat), intent(inout) :: Gfd_tri, Gfo_tri
2791 type(tRgn), intent(in) :: r
2792 type(dSpData1D), intent(inout) :: COHP
2793@@ -424,7 +424,7 @@
2794 integer, pointer :: cncol(:), cptr(:), ccol(:)
2795 integer, pointer :: l_ncol(:), l_ptr(:), l_col(:), col(:)
2796
2797- complex(dp), allocatable :: ph(:)
2798+ complex(dp), pointer :: Gfd(:), Gfo(:)
2799 complex(dp) :: GfGfd
2800 real(dp), pointer :: C(:)
2801 integer :: no_u, br, io, jo, i, ind, iind
2802@@ -444,14 +444,16 @@
2803 call attach(c_sp, n_col=cncol, list_ptr=cptr, list_col=ccol)
2804
2805 ! Create the phases
2806- allocate( ph(0:size(sc_off,dim=2)-1) )
2807 do i = 1 , size(sc_off, dim=2)
2808- ph(i-1) = cdexp(dcmplx(0._dp, &
2809- k(1) * sc_off(1,i) + &
2810- k(2) * sc_off(2,i) + &
2811+ ph(i-1) = cdexp(dcmplx(0._dp, - &
2812+ k(1) * sc_off(1,i) - &
2813+ k(2) * sc_off(2,i) - &
2814 k(3) * sc_off(3,i))) / (2._dp * Pi)
2815 end do
2816
2817+ Gfd => val(Gfd_tri)
2818+ Gfo => val(Gfo_tri)
2819+
2820 !$OMP parallel do default(shared), private(br,io,iind,jo,ind,col,GfGfd)
2821 do br = 1, r%n
2822 io = r%r(br)
2823@@ -476,7 +478,7 @@
2824
2825 if ( ind > l_ptr(jo) ) then
2826
2827- call index_GfGfd(br, pvt%r(jo), GfGfd)
2828+ call calc_GfGfd(br, pvt%r(jo), GfGfd)
2829 ! COHP(iind) += - Im[ (G(io,jo) - G^\dagger(io,jo)) * dH(jo,io)] / 2Pi
2830 C(iind) = C(iind) &
2831 - aimag( GfGfd * dH(ind) * ph( (l_col(ind)-1)/no_u ))
2832@@ -490,37 +492,32 @@
2833 end do
2834 !$OMP end parallel do
2835
2836- deallocate(ph)
2837-
2838 #ifdef TBTRANS_TIMING
2839 call timer('COHP-Gf-dH',2)
2840 #endif
2841
2842 contains
2843
2844- subroutine index_GfGfd(br, bc, G)
2845+ subroutine calc_GfGfd(br, bc, G)
2846 integer, intent(in) :: br, bc
2847- complex(dp), intent(out) :: G
2848- complex(dp), pointer :: Gf(:)
2849- integer :: p_r, i_r, p_c, i_c
2850+ complex(dp), intent(inout) :: G
2851+ integer :: p_r, i_r, p_c, i_c, i
2852
2853 call part_index(Gfo_tri, br, p_r, i_r)
2854 call part_index(Gfo_tri, bc, p_c, i_c)
2855-
2856+
2857 if ( p_r == p_c ) then
2858- Gf => val(Gfd_tri, p_r, p_c)
2859+ i = index_block(Gfo_tri, p_r, p_c)
2860+ G = Gfd(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2861+ G = G - conjg(Gfd(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2862 else
2863- Gf => val(Gfo_tri, p_r, p_c)
2864- end if
2865- G = Gf(i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2866-
2867- ! Immediate subtract G^\dagger element
2868- if ( p_r /= p_c ) then
2869- Gf => val(Gfo_tri, p_c, p_r)
2870- end if
2871- G = G - conjg(Gf(i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2872-
2873- end subroutine index_GfGfd
2874+ i = index_block(Gfo_tri, p_r, p_c)
2875+ G = Gfo(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
2876+ i = index_block(Gfo_tri, p_c, p_r)
2877+ G = G - conjg(Gfo(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
2878+ end if
2879+
2880+ end subroutine calc_GfGfd
2881
2882 function TO(io) result(jo)
2883 integer, intent(in) :: io
2884@@ -553,7 +550,7 @@
2885 ! This routine utilizes the sparse matrix as a loop, instead of looping
2886 ! all BTD matrix elements.
2887 ! This turns out to be much faster for (at least tight-binding calculations).
2888- subroutine A_COP(r,A_tri,pvt,sp,M,sc_off,k,COP)
2889+ subroutine A_COP(r,A_tri,pvt,sp,M,sc_off,k,ph,COP)
2890 use class_Sparsity
2891 use class_dSpData1D
2892 use intrinsic_missing, only : SFIND
2893@@ -566,12 +563,12 @@
2894 real(dp), intent(in) :: M(:) ! S for COOP, H for COHP
2895 real(dp), intent(in) :: sc_off(:,:)
2896 real(dp), intent(in) :: k(3)
2897+ complex(dp), intent(inout) :: ph(0:)
2898 type(dSpData1D), intent(inout) :: COP ! COOP or COHP
2899
2900 type(Sparsity), pointer :: c_sp
2901 real(dp), pointer :: C(:)
2902 complex(dp), pointer :: A(:)
2903- complex(dp), allocatable :: ph(:)
2904 integer, pointer :: ncol(:), l_ptr(:), l_col(:)
2905 integer, pointer :: cncol(:), cptr(:), ccol(:), c_col(:)
2906 integer :: no_u, br, io, ind, iind, bc
2907@@ -590,7 +587,7 @@
2908
2909 ! The COOP calculation can be written as
2910 !
2911- ! COOP(io,jo) = - Im{ A(io,jo) * S(jo,io) * e^(ik.R) } / 2Pi
2912+ ! COOP(io,jo) = Re{ A(io,jo) * S(jo,io) * e^(ik.R) } / 2Pi
2913 ! Here we want:
2914 ! ADOS(io) = \sum_jo COOP(io,jo)
2915 ! since we know that COOP(io,jo) is the io -> jo ADOS.
2916@@ -601,7 +598,6 @@
2917 ! Since we have to do A.S we simply
2918 ! create the S(-k) (which is S^T)
2919 ! and thus get the correct values.
2920- allocate( ph(0:size(sc_off,dim=2)-1) )
2921 do io = 1 , size(sc_off, dim=2)
2922 ph(io-1) = cdexp(dcmplx(0._dp, - &
2923 k(1) * sc_off(1,io) - &
2924@@ -653,16 +649,13 @@
2925 !$OMP end do
2926 !$OMP end parallel
2927
2928- ! Clean-up phases
2929- deallocate(ph)
2930-
2931 #ifdef TBTRANS_TIMING
2932 call timer('A-COP',2)
2933 #endif
2934
2935 end subroutine A_COP
2936
2937- subroutine A_COHP_add_dH(dH_1D,sc_off,k,A_tri,r,COHP,pvt)
2938+ subroutine A_COHP_add_dH(dH_1D,sc_off,k,ph,A_tri,r,COHP,pvt)
2939
2940 use class_Sparsity
2941 use class_zSpData1D
2942@@ -672,6 +665,7 @@
2943
2944 type(zSpData1D), intent(in) :: dH_1D
2945 real(dp), intent(in) :: sc_off(:,:), k(3)
2946+ complex(dp), intent(inout) :: ph(0:)
2947 type(zTriMat), intent(inout) :: A_tri
2948 type(tRgn), intent(in) :: r
2949 type(dSpData1D), intent(inout) :: COHP
2950@@ -684,7 +678,6 @@
2951 integer, pointer :: cncol(:), cptr(:), ccol(:)
2952 integer, pointer :: l_ncol(:), l_ptr(:), l_col(:), col(:)
2953
2954- complex(dp), allocatable :: ph(:)
2955 complex(dp), pointer :: A(:)
2956 real(dp), pointer :: C(:)
2957 integer :: no_u, iu, io, i, ind, iind, jo, iA
2958@@ -704,9 +697,8 @@
2959 call attach(c_sp, n_col=cncol, list_ptr=cptr, list_col=ccol)
2960
2961 ! Create the phases
2962- allocate( ph(0:size(sc_off,dim=2)-1) )
2963 do i = 1 , size(sc_off, dim=2)
2964- ph(i-1) = cdexp(dcmplx(0._dp, &
2965+ ph(i-1) = cdexp(dcmplx(0._dp, + &
2966 k(1) * sc_off(1,i) + &
2967 k(2) * sc_off(2,i) + &
2968 k(3) * sc_off(3,i))) / (2._dp * Pi)
2969@@ -750,8 +742,6 @@
2970 end do
2971 !$OMP end parallel do
2972
2973- deallocate(ph)
2974-
2975 #ifdef TBTRANS_TIMING
2976 call timer('COHP-A-dH',2)
2977 #endif
2978@@ -1568,7 +1558,7 @@
2979
2980
2981 #ifdef NCDF_4
2982- subroutine orb_current(sp,H,S,sc_off,k,cE,A_tri,r,orb_J,pvt)
2983+ subroutine orb_current(sp,H,S,sc_off,k,ph,cE,A_tri,r,orb_J,pvt)
2984
2985 use class_Sparsity
2986 use class_zSpData1D
2987@@ -1582,6 +1572,7 @@
2988 ! We require that the input Hamiltonian is Hermitian
2989 real(dp), intent(in) :: H(:), S(:), sc_off(:,:)
2990 real(dp), intent(in) :: k(3)
2991+ complex(dp), intent(inout) :: ph(0:)
2992 type(ts_c_idx) :: cE
2993 type(zTriMat), intent(inout) :: A_tri
2994 ! The region that specifies the size of orb_J
2995@@ -1594,7 +1585,6 @@
2996 integer, pointer :: i_ncol(:), i_ptr(:), i_col(:), icol(:)
2997 integer, pointer :: l_ncol(:), l_ptr(:), l_col(:)
2998
2999- complex(dp), allocatable :: ph(:)
3000 complex(dp), pointer :: A(:)
3001 complex(dp) :: Hi
3002 real(dp), pointer :: J(:)
3003@@ -1615,12 +1605,9 @@
3004 J => val (orb_J)
3005 call attach(i_sp, n_col=i_ncol, list_ptr=i_ptr, list_col=i_col)
3006
3007- ! We do not initialize J as every entry is overwritten
3008-
3009 ! Create the phases
3010- allocate( ph(0:size(sc_off,dim=2)-1) )
3011 do i = 1 , size(sc_off, dim=2)
3012- ph(i-1) = cdexp(dcmplx(0._dp, &
3013+ ph(i-1) = cdexp(dcmplx(0._dp, + &
3014 k(1) * sc_off(1,i) + &
3015 k(2) * sc_off(2,i) + &
3016 k(3) * sc_off(3,i)))
3017@@ -1685,15 +1672,13 @@
3018 !$OMP end do
3019 !$OMP end parallel
3020
3021- deallocate(ph)
3022-
3023 #ifdef TBTRANS_TIMING
3024 call timer('orb-current',2)
3025 #endif
3026
3027 end subroutine orb_current
3028
3029- subroutine orb_current_add_dH(dH_1D,sc_off,k,A_tri,r,orb_J,pvt)
3030+ subroutine orb_current_add_dH(dH_1D,sc_off,k,ph,A_tri,r,orb_J,pvt)
3031
3032 use class_Sparsity
3033 use class_zSpData1D
3034@@ -1703,6 +1688,7 @@
3035
3036 type(zSpData1D), intent(in) :: dH_1D
3037 real(dp), intent(in) :: sc_off(:,:), k(3)
3038+ complex(dp), intent(inout) :: ph(0:)
3039 type(zTriMat), intent(inout) :: A_tri
3040 ! The region that specifies the size of orb_J
3041 type(tRgn), intent(in) :: r
3042@@ -1716,7 +1702,6 @@
3043 integer, pointer :: i_ncol(:), i_ptr(:), i_col(:)
3044 integer, pointer :: l_ncol(:), l_ptr(:), l_col(:), col(:)
3045
3046- complex(dp), allocatable :: ph(:)
3047 complex(dp) :: p
3048 complex(dp), pointer :: A(:)
3049 real(dp), pointer :: J(:)
3050@@ -1737,9 +1722,8 @@
3051 call attach(i_sp, n_col=i_ncol, list_ptr=i_ptr, list_col=i_col)
3052
3053 ! Create the phases
3054- allocate( ph(0:size(sc_off,dim=2)-1) )
3055 do i = 1 , size(sc_off, dim=2)
3056- ph(i-1) = cdexp(dcmplx(0._dp, &
3057+ ph(i-1) = cdexp(dcmplx(0._dp, + &
3058 k(1) * sc_off(1,i) + &
3059 k(2) * sc_off(2,i) + &
3060 k(3) * sc_off(3,i)))
3061@@ -1817,8 +1801,6 @@
3062 end do
3063 !$OMP end parallel do
3064
3065- deallocate(ph)
3066-
3067 #ifdef TBTRANS_TIMING
3068 call timer('orb-current-dH',2)
3069 #endif
3070@@ -1851,6 +1833,183 @@
3071 end function TO
3072
3073 end subroutine orb_current_add_dH
3074+
3075+
3076+ subroutine GF_DM(sc_off,k,ph,Gfd_tri,Gfo_tri,r,pvt,spDM)
3077+
3078+ use class_Sparsity
3079+ use class_dSpData1D
3080+ use geom_helper, only : UCORB
3081+
3082+ real(dp), intent(in) :: sc_off(:,:)
3083+ real(dp), intent(in) :: k(3)
3084+ complex(dp), intent(inout) :: ph(0:)
3085+ type(zTriMat), intent(inout) :: Gfd_tri, Gfo_tri
3086+ ! The region that specifies the size of spDM
3087+ type(tRgn), intent(in) :: r
3088+ ! The pivoting region that transfers r%r(iu) to io
3089+ type(tRgn), intent(in) :: pvt
3090+ type(dSpData1D), intent(inout) :: spDM
3091+
3092+ integer, pointer :: ncol(:), l_ptr(:), l_col(:)
3093+
3094+ type(Sparsity), pointer :: sp
3095+ real(dp), pointer :: DM(:)
3096+ complex(dp), pointer :: Gfd(:), Gfo(:)
3097+ complex(dp) :: GfGfd
3098+
3099+ integer :: no_u, iu, io, ind, ju
3100+
3101+#ifdef TBTRANS_TIMING
3102+ call timer('Gf-DM',1)
3103+#endif
3104+
3105+ sp => spar(spDM)
3106+ DM => val(spDM)
3107+ call attach(sp, nrows_g=no_u, n_col=ncol, list_ptr=l_ptr, list_col=l_col)
3108+
3109+ ! Create the phases
3110+ do io = 1 , size(sc_off, dim=2)
3111+ ph(io-1) = cdexp(dcmplx(0._dp, - &
3112+ k(1) * sc_off(1,io) - &
3113+ k(2) * sc_off(2,io) - &
3114+ k(3) * sc_off(3,io))) / (2._dp * Pi)
3115+ end do
3116+
3117+ Gfd => val(Gfd_tri)
3118+ Gfo => val(Gfo_tri)
3119+
3120+!$OMP parallel default(shared), private(iu,io,ind,ju,GfGfd)
3121+
3122+ ! we need this in case the device region gets enlarged due to dH
3123+!$OMP workshare
3124+ DM(:) = 0._dp
3125+!$OMP end workshare
3126+
3127+!$OMP do
3128+ do iu = 1, r%n
3129+ io = r%r(iu)
3130+
3131+#ifndef TS_NOCHECKS
3132+ if ( ncol(io) == 0 ) call die('Gf_DM: DM has zero columns &
3133+ &for at least one row')
3134+#endif
3135+
3136+ ! Loop on DM entries here...
3137+ do ind = l_ptr(io) + 1 , l_ptr(io) + ncol(io)
3138+
3139+ ju = pvt%r(ucorb(l_col(ind), no_u))
3140+ call calc_GfGfd(iu, ju, GfGfd)
3141+ DM(ind) = - aimag( GfGfd * ph((l_col(ind) - 1) / no_u) )
3142+
3143+ end do
3144+ end do
3145+!$OMP end do
3146+!$OMP end parallel
3147+
3148+#ifdef TBTRANS_TIMING
3149+ call timer('Gf-DM',2)
3150+#endif
3151+
3152+ contains
3153+
3154+ subroutine calc_GfGfd(br, bc, G)
3155+ integer, intent(in) :: br, bc
3156+ complex(dp), intent(inout) :: G
3157+ integer :: p_r, i_r, p_c, i_c, i
3158+
3159+ call part_index(Gfo_tri, br, p_r, i_r)
3160+ call part_index(Gfo_tri, bc, p_c, i_c)
3161+
3162+ if ( p_r == p_c ) then
3163+ i = index_block(Gfo_tri, p_r, p_c)
3164+ G = Gfd(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
3165+ G = G - conjg(Gfd(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
3166+ else
3167+ i = index_block(Gfo_tri, p_r, p_c)
3168+ G = Gfo(i + i_r + (i_c-1) * Gfo_tri%data%tri_nrows(p_r))
3169+ i = index_block(Gfo_tri, p_c, p_r)
3170+ G = G - conjg(Gfo(i + i_c + (i_r-1) * Gfo_tri%data%tri_nrows(p_c)))
3171+ end if
3172+
3173+ end subroutine calc_GfGfd
3174+
3175+ end subroutine GF_DM
3176+
3177+ subroutine A_DM(sc_off,k,ph,A_tri,r,pvt,spDM)
3178+
3179+ use class_Sparsity
3180+ use class_dSpData1D
3181+ use geom_helper, only : UCORB
3182+
3183+ real(dp), intent(in) :: sc_off(:,:)
3184+ real(dp), intent(in) :: k(3)
3185+ complex(dp), intent(inout) :: ph(0:)
3186+ type(zTriMat), intent(inout) :: A_tri
3187+ ! The region that specifies the size of spDM
3188+ type(tRgn), intent(in) :: r
3189+ ! The pivoting region that transfers r%r(iu) to io
3190+ type(tRgn), intent(in) :: pvt
3191+ type(dSpData1D), intent(inout) :: spDM
3192+
3193+ integer, pointer :: ncol(:), l_ptr(:), l_col(:)
3194+
3195+ type(Sparsity), pointer :: sp
3196+ complex(dp), pointer :: A(:)
3197+ real(dp), pointer :: DM(:)
3198+ integer :: no_u, iu, io, ind, ju
3199+
3200+#ifdef TBTRANS_TIMING
3201+ call timer('A-DM',1)
3202+#endif
3203+
3204+ sp => spar(spDM)
3205+ DM => val(spDM)
3206+ call attach(sp, nrows_g=no_u, n_col=ncol, list_ptr=l_ptr, list_col=l_col)
3207+
3208+ ! Create the phases
3209+ do io = 1 , size(sc_off, dim=2)
3210+ ph(io-1) = cdexp(dcmplx(0._dp, - &
3211+ k(1) * sc_off(1,io) - &
3212+ k(2) * sc_off(2,io) - &
3213+ k(3) * sc_off(3,io))) / (2._dp * Pi)
3214+ end do
3215+
3216+ A => val(A_tri)
3217+!$OMP parallel default(shared), private(iu,io,ind,ju)
3218+
3219+ ! we need this in case the device region gets enlarged due to dH
3220+!$OMP workshare
3221+ DM(:) = 0._dp
3222+!$OMP end workshare
3223+
3224+!$OMP do
3225+ do iu = 1, r%n
3226+ io = r%r(iu)
3227+
3228+#ifndef TS_NOCHECKS
3229+ if ( ncol(io) == 0 ) call die('A_DM: DM has zero columns &
3230+ &for at least one row')
3231+#endif
3232+
3233+ ! Loop on DM entries here...
3234+ do ind = l_ptr(io) + 1 , l_ptr(io) + ncol(io)
3235+
3236+ ju = pvt%r(ucorb(l_col(ind), no_u))
3237+ ju = index(A_tri, iu, ju)
3238+ DM(ind) = real(A(ju) * ph((l_col(ind) - 1) / no_u), dp)
3239+
3240+ end do
3241+ end do
3242+!$OMP end do
3243+!$OMP end parallel
3244+
3245+#ifdef TBTRANS_TIMING
3246+ call timer('A-DM',2)
3247+#endif
3248+
3249+ end subroutine A_DM
3250+
3251 #endif
3252
3253 subroutine insert_Self_energy(n1,n2,M,r,El,off1,off2)
3254@@ -1968,202 +2127,4 @@
3255
3256 end subroutine insert_Self_energy_Dev
3257
3258-
3259-#ifdef THESE_HAVE_BEEN_SUPERSEEDED
3260-
3261- ! A simple routine to calculate the DOS
3262- ! from a partially calculated GF
3263- ! When entering this routine Gf_tri
3264- ! should contain:
3265- ! all GF_nn
3266- ! all Yn/Bn-1 and all Xn/Cn+1
3267- ! This lets us calculate all entries
3268- subroutine GF_DOS_loop_BTD(r,Gf_tri,S_1D,DOS,nwork,work)
3269- use intrinsic_missing, only : SFIND
3270- use class_Sparsity
3271- use class_zSpData1D
3272-
3273- type(tRgn), intent(in) :: r
3274- type(zTriMat), intent(inout) :: Gf_tri
3275- type(zSpData1D), intent(inout) :: S_1D
3276- real(dp), intent(out) :: DOS(r%n)
3277- integer, intent(in) :: nwork
3278- complex(dp), intent(inout), target :: work(nwork)
3279-
3280- type(Sparsity), pointer :: sp
3281- complex(dp), pointer :: S(:), Gf(:), Mnn(:), XY(:)
3282- integer, pointer :: ncol(:), l_ptr(:), l_col(:), lcol(:)
3283- integer :: off1, off2, n, in
3284- integer :: jo, i, j, no_o, no_i, ind, np
3285- real(dp) :: lDOS
3286-
3287-#ifdef TBTRANS_TIMING
3288- call timer('GF-DOS',1)
3289-#endif
3290-
3291- S => val(S_1D)
3292- sp => spar(S_1D)
3293- call attach(sp,n_col=ncol,list_ptr=l_ptr,list_col=l_col)
3294-
3295- ! Initialize DOS to 0
3296-!$OMP parallel workshare default(shared)
3297- DOS(:) = 0._dp
3298-!$OMP end parallel workshare
3299-
3300- off2 = 0
3301- np = parts(Gf_tri)
3302- do n = 1 , np
3303-
3304- no_o = nrows_g(Gf_tri,n)
3305-
3306- do in = max(1,n-1) , min(n+1,np)
3307-
3308- no_i = nrows_g(Gf_tri,in)
3309-
3310- if ( in < n ) then
3311- off1 = off2 - no_i
3312- else if ( n < in ) then
3313- off1 = off2 + no_o
3314- else
3315- off1 = off2
3316- end if
3317-
3318- if ( in == n ) then
3319- ! Retrieve the central part of the
3320- ! matrix
3321- Gf => val(Gf_tri,n,n)
3322-
3323- else
3324-
3325- XY => val(Gf_tri,in,n)
3326- Mnn => val(Gf_tri,n,n)
3327-
3328- Gf => work(1:no_o*no_i)
3329-
3330- ! We need to calculate the
3331- ! Mnm1n/Mnp1n Green's function
3332-#ifdef USE_GEMM3M
3333- call zgemm3m( &
3334-#else
3335- call zgemm( &
3336-#endif
3337- 'N','N',no_i,no_o,no_o, &
3338- zm1, XY,no_i, Mnn,no_o,z0, Gf,no_i)
3339-
3340- end if
3341-
3342-!$OMP parallel do default(shared), private(j,jo,ind,i,lcol,lDOS)
3343- do j = 1 , no_o
3344- jo = r%r(off2+j)
3345- lcol => l_col(l_ptr(jo)+1:l_ptr(jo)+ncol(jo))
3346- ! get the equivalent one in the
3347- ! overlap matrix
3348- ! REMEMBER, S is transposed!
3349- ! Hence we do not need conjg :)
3350- lDOS = 0._dp
3351- do i = 1 , no_i
3352- ind = SFIND(lcol,r%r(off1+i))
3353- if ( ind == 0 ) cycle
3354- ind = l_ptr(jo) + ind
3355- lDOS = lDOS - dimag( Gf(j+(i-1)*no_i) * S(ind) )
3356- end do
3357- DOS(off2+j) = DOS(off2+j) + lDOS / Pi
3358- end do
3359-!$OMP end parallel do
3360-
3361- end do
3362-
3363- ! Update the offset
3364- off2 = off2 + no_o
3365-
3366- end do
3367-
3368-#ifdef TBTRANS_TIMING
3369- call timer('GF-DOS',2)
3370-#endif
3371-
3372- end subroutine GF_DOS_loop_BTD
3373-
3374- ! A simple routine to calculate the DOS
3375- ! from a full calculated spectral function
3376- ! This loops over entries in the BTD matrix.
3377- subroutine A_DOS_loop_BTD(r,A_tri,S_1D,DOS)
3378- use intrinsic_missing, only : SFIND
3379- use class_Sparsity
3380- use class_zSpData1D
3381-
3382- type(tRgn), intent(in) :: r
3383- type(zTriMat), intent(inout) :: A_tri
3384- type(zSpData1D), intent(inout) :: S_1D
3385- real(dp), intent(out) :: DOS(r%n)
3386-
3387- type(Sparsity), pointer :: sp
3388- complex(dp), pointer :: S(:), A(:)
3389- integer, pointer :: ncol(:), l_ptr(:), l_col(:), lcol(:)
3390- integer :: off1, off2, n, in
3391- integer :: jo, i, j, no_o, no_i, ind, np
3392- real(dp) :: lDOS
3393-
3394-#ifdef TBTRANS_TIMING
3395- call timer('A-DOS',1)
3396-#endif
3397-
3398- S => val(S_1D)
3399- sp => spar(S_1D)
3400- call attach(sp,n_col=ncol,list_ptr=l_ptr,list_col=l_col)
3401-
3402- off2 = 0
3403- np = parts(A_tri)
3404- do n = 1 , np
3405-
3406- no_o = nrows_g(A_tri,n)
3407-
3408- do in = max(1,n-1) , min(n+1,np)
3409-
3410- A => val(A_tri,in,n)
3411-
3412- no_i = nrows_g(A_tri,in)
3413-
3414- if ( in < n ) then
3415- off1 = off2 - no_i
3416- else if ( n < in ) then
3417- off1 = off2 + no_o
3418- else
3419- off1 = off2
3420- end if
3421-
3422-!$OMP parallel do default(shared), private(j,jo,ind,i,lcol,lDOS)
3423- do j = 1 , no_o
3424- jo = r%r(off2+j)
3425- lcol => l_col(l_ptr(jo)+1:l_ptr(jo)+ncol(jo))
3426- ! get the equivalent one in the
3427- ! overlap matrix
3428- ! REMEMBER, S is transposed!
3429- ! Hence we are doing it correctly
3430- lDOS = 0._dp
3431- do i = 1 , no_i
3432- ind = SFIND(lcol,r%r(off1+i))
3433- if ( ind == 0 ) cycle
3434- ind = l_ptr(jo) + ind
3435- lDOS = lDOS + dreal( A(j+(i-1)*no_i) * S(ind) )
3436- end do
3437- DOS(off2+j) = DOS(off2+j) + lDOS / (2._dp * Pi)
3438- end do
3439-!$OMP end parallel do
3440-
3441- end do
3442-
3443- ! Update the offset
3444- off2 = off2 + no_o
3445-
3446- end do
3447-
3448-#ifdef TBTRANS_TIMING
3449- call timer('A-DOS',2)
3450-#endif
3451-
3452- end subroutine A_DOS_loop_BTD
3453-
3454-#endif
3455-
3456 end module m_tbt_tri_scat
3457
3458=== modified file 'Util/TS/TBtrans/m_tbt_trik.F90'
3459--- Util/TS/TBtrans/m_tbt_trik.F90 2018-03-28 07:50:09 +0000
3460+++ Util/TS/TBtrans/m_tbt_trik.F90 2018-05-04 19:08:45 +0000
3461@@ -151,8 +151,12 @@
3462 real(dp), pointer :: H2D(:,:), S(:), H(:)
3463 ! To figure out which parts of the tri-diagonal blocks we need
3464 ! to calculate
3465- logical :: calc_DOS_Gf, calc_DOS_A, calc_orb_current
3466+ logical :: calc_T_Gf, calc_T_out
3467+ logical :: calc_DOS_Elecs
3468+ logical :: calc_DOS_Gf, calc_DOS_A
3469 #ifdef NCDF_4
3470+ logical :: calc_orb_current
3471+ logical :: calc_DM_Gf, calc_DM_A
3472 logical :: calc_COOP_Gf, calc_COOP_A
3473 logical :: calc_COHP_Gf, calc_COHP_A
3474 #endif
3475@@ -188,7 +192,7 @@
3476 type(tLvlMolEl), pointer :: p_E
3477 real(dp), allocatable :: pDOS(:,:,:)
3478 real(dp), allocatable :: bTk(:,:), bTkeig(:,:,:)
3479- type(dSpData1D) :: orb_J
3480+ type(dSpData1D) :: dev_M
3481 #endif
3482 ! ************************************************************
3483
3484@@ -196,7 +200,7 @@
3485 integer :: nGFGGF ! For the triple-product
3486 complex(dp), pointer :: GFGGF_work(:) => null()
3487 integer :: ntt_work
3488- complex(dp), pointer :: tt_work(:), eig(:)
3489+ complex(dp), pointer :: tt_work(:), eig(:), phase(:)
3490 ! ************************************************************
3491
3492 ! ******************* Computational variables ****************
3493@@ -242,12 +246,17 @@
3494 real :: last_progress, cur_progress
3495 ! ************************************************************
3496
3497+ calc_DOS_Elecs = 'DOS-Elecs' .in. save_DATA
3498+ calc_T_Gf = 'T-Gf' .in. save_DATA
3499+ calc_T_out = 'T-sum-out' .in. save_DATA
3500 calc_DOS_Gf = 'DOS-Gf' .in. save_DATA
3501 calc_DOS_A = 'DOS-A' .in. save_DATA
3502- calc_orb_current = 'orb-current' .in. save_DATA
3503 T_all = 'T-all' .in. save_DATA
3504 ADOS_all = 'DOS-A-all' .in. save_DATA
3505 #ifdef NCDF_4
3506+ calc_orb_current = 'orb-current' .in. save_DATA
3507+ calc_DM_Gf = 'DM-Gf' .in. save_DATA
3508+ calc_DM_A = 'DM-A' .in. save_DATA
3509 calc_COOP_Gf = 'COOP-Gf' .in. save_DATA
3510 calc_COOP_A = 'COOP-A' .in. save_DATA
3511 calc_COHP_Gf = 'COHP-Gf' .in. save_DATA
3512@@ -437,14 +446,6 @@
3513 end if
3514
3515
3516- ! Note that padding is the extra size to be able to calculate
3517- ! the spectral function in the BTD format
3518-
3519- ! We allocate for the matrix
3520- call print_memory('LHS',pad_LHS)
3521- call newzTriMat(zwork_tri,DevTri%n,DevTri%r,'GFinv', &
3522- padding = pad_LHS )
3523-
3524 ! The RHS will be the array that retains the
3525 ! self-energies and nothing more.
3526 ! Here we pad with the missing elements to contain
3527@@ -461,10 +462,25 @@
3528 ! this is only preferred in tbtrans as there might be
3529 ! padding any-way.
3530 pad_RHS = max(pad_RHS,nGFGGF)
3531+
3532+ ! Ensure that at least one of the work arrays has
3533+ ! elements for the few supercells
3534+ io = product(TSHS%nsc)
3535+ if ( pad_LHS < io .and. pad_RHS < io ) then
3536+ pad_LHS = io
3537+ end if
3538
3539+ ! Note that padding is the extra size to be able to calculate
3540+ ! the spectral function in the BTD format
3541+
3542+ ! We allocate for the matrix
3543+ call print_memory('LHS',pad_LHS)
3544+ call newzTriMat(zwork_tri,DevTri%n,DevTri%r,'GFinv', &
3545+ padding = pad_LHS )
3546+
3547 call print_memory('RHS',pad_RHS)
3548 call newzTriMat(GF_tri,DevTri%n,DevTri%r,'GF', &
3549- padding = pad_RHS )
3550+ padding = pad_RHS )
3551
3552 ! Create the work-array...
3553 zwork => val(zwork_tri,all=.true.)
3554@@ -472,12 +488,23 @@
3555 Gfwork => val(Gf_tri,all=.true.)
3556 nGfwork = size(Gfwork)
3557 if ( nGfwork > nzwork ) then
3558- nmaxwork = nGfwork
3559- maxwork => Gfwork(:)
3560- else
3561- nmaxwork = nzwork
3562- maxwork => zwork(:)
3563- end if
3564+ nmaxwork = nGfwork
3565+ maxwork => Gfwork(:)
3566+ else
3567+ nmaxwork = nzwork
3568+ maxwork => zwork(:)
3569+ end if
3570+
3571+ ! Create phase array
3572+ io = product(TSHS%nsc)
3573+ if ( pad_LHS >= io ) then
3574+ phase => zwork(nzwork-io+1:)
3575+ else if ( pad_RHS >= io ) then
3576+ phase => Gfwork(nGfwork-io+1:)
3577+ else
3578+ call die('Error in coding! Phase size!')
3579+ end if
3580+
3581
3582 ! Point the work-array for eigenvalue calculation
3583 if ( N_eigen > 0 ) then
3584@@ -601,8 +628,7 @@
3585 ! The first partition is whether we want
3586 ! certain quantities from all electrodes
3587 A_parts(:) = .false.
3588- if ( T_all .or. &
3589- ('T-sum-out' .in. save_DATA) ) then
3590+ if ( T_all .or. calc_T_out ) then
3591
3592 ! We need _all_ diagonal blocks of the spectral function
3593 do iEl = 1 , N_Elec
3594@@ -651,10 +677,11 @@
3595
3596 #ifdef NCDF_4
3597 if ( calc_orb_current .or. ('proj-orb-current'.in.save_DATA) .or. &
3598+ calc_DM_Gf .or. calc_DM_A .or. &
3599 calc_COOP_Gf .or. calc_COOP_A .or. &
3600 calc_COHP_Gf .or. calc_COHP_A ) then
3601
3602- call newdSpData1D(sp_dev_sc,fdist,orb_J,name='TBT sparse')
3603+ call newdSpData1D(sp_dev_sc,fdist,dev_M,name='TBT sparse')
3604
3605 end if
3606 #endif
3607@@ -845,7 +872,7 @@
3608 ! We have reduced the electrode sizes to only one spin-channel
3609 ! Hence, it will ALWAYS be the first index
3610 if ( n_k == 0 ) then
3611- if ( 'DOS-Elecs' .in. save_DATA ) then
3612+ if ( calc_DOS_Elecs ) then
3613 call read_next_GS(1, ikpt, bkpt, &
3614 cE, N_Elec, uGF, Elecs, &
3615 nzwork, zwork, .false., forward = .false. , &
3616@@ -997,7 +1024,7 @@
3617 if ( .not. only_proj ) then
3618 #endif
3619
3620- call timer('DOS-Gf-A-T',1)
3621+ call timer('analysis',1)
3622
3623 ! We have now calculated all block diagonal entries
3624 ! of the Green's function.
3625@@ -1012,19 +1039,23 @@
3626 end if
3627
3628 #ifdef NCDF_4
3629+ if ( calc_DM_Gf ) then
3630+ call Gf_DM(TSHS%sc_off,kpt,phase,Gf_tri,zwork_tri,r_oDev,pvt, dev_M)
3631+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'DM', dev_M)
3632+ end if
3633 if ( calc_COOP_Gf ) then
3634 call GF_COP(r_oDev,Gf_tri,zwork_tri,pvt, &
3635- TSHS%sp,S,TSHS%sc_off, kpt, orb_J)
3636- call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COOP', orb_J)
3637+ TSHS%sp,S,TSHS%sc_off, kpt, phase, dev_M)
3638+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COOP', dev_M)
3639 end if
3640 if ( calc_COHP_Gf ) then
3641 call GF_COP(r_oDev,Gf_tri,zwork_tri,pvt, &
3642- TSHS%sp,H,TSHS%sc_off, kpt, orb_J)
3643+ TSHS%sp,H,TSHS%sc_off, kpt, phase, dev_M)
3644 if ( dH%lvl > 0 ) then
3645- call GF_COHP_add_dH(dH%d, TSHS%sc_off, &
3646- kpt, Gf_tri, zwork_tri, r_oDev, orb_J, pvt)
3647+ call GF_COHP_add_dH(dH%d, TSHS%sc_off, kpt, &
3648+ phase, Gf_tri, zwork_tri, r_oDev, dev_M, pvt)
3649 end if
3650- call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COHP', orb_J)
3651+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COHP', dev_M)
3652 end if
3653 #endif
3654
3655@@ -1033,7 +1064,7 @@
3656 ! ****************
3657 ! * Column Gf *
3658 ! ****************
3659- if ( 'T-Gf' .in. save_DATA ) then
3660+ if ( calc_T_Gf ) then
3661
3662 ! We are allowed to calculate the transmission
3663 ! only by using the diagonal
3664@@ -1070,7 +1101,7 @@
3665 call invert_BiasTriMat_rgn(GF_tri,zwork_tri, &
3666 r_oDev, pvt, Elecs(iEl)%o_inD)
3667
3668- if ( 'T-sum-out' .in. save_DATA ) then
3669+ if ( calc_T_out ) then
3670 call Gf_Gamma(zwork_tri,Elecs(iEl),T(N_Elec+1,iEl))
3671 end if
3672
3673@@ -1092,7 +1123,7 @@
3674 ! * calc A-matrix *
3675 ! *****************
3676 if ( .not. cE%fake ) then
3677- if ( 'T-sum-out' .in. save_DATA ) then
3678+ if ( calc_T_out ) then
3679 call dir_GF_Gamma_GF(Gf_tri, zwork_tri, r_oDev, pvt, &
3680 Elecs(iEl), A_parts, &
3681 TrGfG = T(N_Elec+1,iEl))
3682@@ -1114,20 +1145,25 @@
3683 end if
3684
3685 #ifdef NCDF_4
3686+ if ( calc_DM_A ) then
3687+ call A_DM(TSHS%sc_off,kpt,phase,zwork_tri,r_oDev,pvt, dev_M)
3688+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'DM', dev_M, &
3689+ Elecs(iEl))
3690+ end if
3691 if ( calc_COOP_A ) then
3692 call A_COP(r_oDev,zwork_tri,pvt, &
3693- TSHS%sp,S,TSHS%sc_off, kpt, orb_J)
3694- call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COOP', orb_J, &
3695+ TSHS%sp,S,TSHS%sc_off, kpt, phase, dev_M)
3696+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COOP', dev_M, &
3697 Elecs(iEl))
3698 end if
3699 if ( calc_COHP_A ) then
3700 call A_COP(r_oDev,zwork_tri,pvt, &
3701- TSHS%sp,H,TSHS%sc_off, kpt, orb_J)
3702+ TSHS%sp,H,TSHS%sc_off, kpt, phase, dev_M)
3703 if ( dH%lvl > 0 ) then
3704 call A_COHP_add_dH(dH%d, TSHS%sc_off, &
3705- kpt, zwork_tri, r_oDev, orb_J, pvt)
3706+ kpt, phase, zwork_tri, r_oDev, dev_M, pvt)
3707 end if
3708- call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COHP', orb_J, &
3709+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'COHP', dev_M, &
3710 Elecs(iEl))
3711 end if
3712
3713@@ -1135,21 +1171,21 @@
3714
3715 #ifdef TBT_PHONON
3716 call orb_current(TSHS%sp,H,S,TSHS%sc_off, &
3717- kpt, &
3718- cOmega,zwork_tri,r_oDev,orb_J,pvt)
3719+ kpt, phase, &
3720+ cOmega,zwork_tri,r_oDev,dev_M,pvt)
3721 #else
3722 call orb_current(TSHS%sp,H,S,TSHS%sc_off, &
3723- kpt, &
3724- cE,zwork_tri,r_oDev,orb_J,pvt)
3725+ kpt, phase, &
3726+ cE,zwork_tri,r_oDev,dev_M,pvt)
3727 #endif
3728 if ( dH%lvl > 0 ) then
3729 call orb_current_add_dH(dH%d, TSHS%sc_off, &
3730- kpt, zwork_tri, r_oDev, orb_J, pvt)
3731+ kpt, phase, zwork_tri, r_oDev, dev_M, pvt)
3732 end if
3733
3734 ! We need to save it immediately, we
3735 ! do not want to have several arrays in memory
3736- call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'J', orb_J, &
3737+ call state_cdf_save_sp_dev(TBTcdf, ikpt, nE, 'J', dev_M, &
3738 Elecs(iEl))
3739
3740 end if
3741@@ -1163,8 +1199,7 @@
3742 ! calculate this.
3743 if ( (.not. T_all) .and. &
3744 jEl < iEl ) cycle
3745- if ( ('T-sum-out' .nin. save_DATA ) .and. &
3746- iEl == jEl ) cycle
3747+ if ( (.not. calc_T_out) .and. iEl == jEl ) cycle
3748
3749 ! Notice that the Gf.G1.Gf.G2 can be performed
3750 ! for all other electrodes as long as we
3751@@ -1210,7 +1245,7 @@
3752 save_DATA )
3753 #endif
3754
3755- call timer('DOS-Gf-A-T',2)
3756+ call timer('analysis',2)
3757 #ifdef NCDF_4
3758 end if ! .not. proj-only
3759 end if ! .not. Sigma-only
3760@@ -1221,7 +1256,7 @@
3761
3762 if ( N_proj_T > 0 ) then
3763
3764- call timer('T-proj',1)
3765+ call timer('analysis-proj',1)
3766
3767 ! Calculate the projections
3768 do ipt = 1 , N_proj_T
3769@@ -1236,7 +1271,7 @@
3770 ! superfluous checks in the following block
3771 if ( ('proj-orb-current' .in. save_DATA) .and. p_E%idx > 0 ) then
3772
3773- call proj_cdf_save_J(PROJcdf, ikpt, nE, p_E, orb_J)
3774+ call proj_cdf_save_J(PROJcdf, ikpt, nE, p_E, dev_M)
3775
3776 end if
3777 #endif
3778@@ -1305,7 +1340,7 @@
3779 bTk(1+size(proj_T(ipt)%R),ipt))
3780 end if
3781 else
3782- if ( 'T-sum-out' .in. save_DATA ) then
3783+ if ( 'proj-T-sum-out' .in. save_DATA ) then
3784 call dir_GF_Gamma_GF(Gf_tri, zwork_tri, r_oDev, pvt, &
3785 Elecs(iEl), proj_parts, &
3786 TrGfG = bTk(1+size(proj_T(ipt)%R),ipt))
3787@@ -1336,22 +1371,22 @@
3788
3789 #ifdef TBT_PHONON
3790 call orb_current(TSHS%sp,H,S,TSHS%sc_off, &
3791- kpt, &
3792- cOmega,zwork_tri,r_oDev,orb_J,pvt)
3793+ kpt, phase, &
3794+ cOmega,zwork_tri,r_oDev,dev_M,pvt)
3795 #else
3796 call orb_current(TSHS%sp,H,S,TSHS%sc_off, &
3797- kpt, &
3798- cE,zwork_tri,r_oDev,orb_J,pvt)
3799+ kpt, phase, &
3800+ cE,zwork_tri,r_oDev,dev_M,pvt)
3801 #endif
3802 if ( dH%lvl > 0 ) then
3803 call orb_current_add_dH(dH%d, TSHS%sc_off, &
3804- kpt, zwork_tri, r_oDev, orb_J, pvt)
3805+ kpt, phase, zwork_tri, r_oDev, dev_M, pvt)
3806 end if
3807
3808 ! We need to save it immediately, we
3809 ! do not want to have several arrays in the
3810 ! memory
3811- call proj_cdf_save_J(PROJcdf, ikpt, nE, p_E, orb_J)
3812+ call proj_cdf_save_J(PROJcdf, ikpt, nE, p_E, dev_M)
3813
3814 end if
3815 #endif
3816@@ -1426,7 +1461,7 @@
3817 ikpt,nE,N_proj_T,proj_T, &
3818 pDOS, bTk, N_eigen, bTkeig, save_DATA )
3819
3820- call timer('T-proj',2)
3821+ call timer('analysis-proj',2)
3822
3823 end if
3824 #endif
3825@@ -1514,7 +1549,7 @@
3826 deallocate(bTkeig)
3827 end if
3828
3829- call delete(orb_J)
3830+ call delete(dev_M)
3831
3832 ! Before we delete the Gf tri-diagonal matrix
3833 ! we need to create the sigma mean if requested.
3834
3835=== modified file 'Util/TS/TBtrans/m_tbtrans.F90'
3836--- Util/TS/TBtrans/m_tbtrans.F90 2018-04-09 12:39:44 +0000
3837+++ Util/TS/TBtrans/m_tbtrans.F90 2018-05-04 19:08:45 +0000
3838@@ -301,18 +301,18 @@
3839 call name_save( ispin, TSHS%nspin,cdf_fname, end = 'nc')
3840 call init_cdf_save(cdf_fname,TSHS,r_oDev,DevTri,ispin, &
3841 N_Elec, Elecs, r_oElpd, ElTri, &
3842- nkpt, kpt, wkpt, NEn, r_aDev, r_aBuf, sp_dev_sc, save_DATA )
3843+ nkpt, kpt, wkpt, NEn, tbt_Eta, r_aDev, r_aBuf, sp_dev_sc, save_DATA )
3844 end if
3845
3846 call name_save( ispin, TSHS%nspin,cdf_fname_sigma, end = 'SE.nc')
3847 call init_Sigma_save(cdf_fname_sigma,TSHS,r_oDev,DevTri,ispin,N_Elec, Elecs, &
3848- nkpt, kpt, wkpt, NEn, r_aDev, r_aBuf )
3849+ nkpt, kpt, wkpt, NEn, tbt_Eta, r_aDev, r_aBuf )
3850
3851 if ( ('Sigma-only'.nin.save_DATA) ) then
3852
3853 call name_save( ispin, TSHS%nspin, cdf_fname_proj, end = 'Proj.nc' )
3854 call init_Proj_save( cdf_fname_proj,TSHS,r_oDev,DevTri,ispin, N_Elec, Elecs, &
3855- nkpt, kpt, wkpt, NEn , r_aDev, r_aBuf, sp_dev_sc, save_DATA )
3856+ nkpt, kpt, wkpt, NEn, tbt_Eta, r_aDev, r_aBuf, sp_dev_sc, save_DATA )
3857 end if
3858
3859 if ( n_k /= 0 ) then
3860
3861=== modified file 'version.info'
3862--- version.info 2018-04-27 09:35:52 +0000
3863+++ version.info 2018-05-04 19:08:45 +0000
3864@@ -1,2 +1,1 @@
3865-siesta-4.1--903
3866-
3867+siesta-4.1--903--ts-10

Subscribers

People subscribed via source and target branches