1#!/usr/local/bin/python3.8
2r"""
3Flow for e-Bands with frozen phonon
4===================================
5
6Electronic band structure of silicon in a distorted geometry (frozen phonon at q=0)
7"""
8
9import sys
10import os
11import numpy as np
12import abipy.data as data
13import abipy.abilab as abilab
14import abipy.flowtk as flowtk
15
16
17def make_scf_nscf_inputs(structure, paral_kgb=1):
18    multi = abilab.MultiDataset(structure, pseudos=data.pseudos("14si.pspnc"), ndtset=2)
19
20    # Global variables
21    global_vars = dict(
22        ecut=6,
23        nband=8,
24        timopt=-1,
25        paral_kgb=0,
26        #nstep=4, # This is not enough to converge. Used to test the automatic restart.
27        nstep=10,
28        iomode=3,
29    )
30
31    multi.set_vars(global_vars)
32
33    # Dataset 1 (GS run)
34    multi[0].set_kmesh(ngkpt=[8,8,8], shiftk=[0,0,0])
35    multi[0].set_vars(tolvrs=1e-6)
36
37    # Dataset 2 (NSCF run)
38    kptbounds = [
39        [0.5, 0.0, 0.0], # L point
40        [0.0, 0.0, 0.0], # Gamma point
41        [0.0, 0.5, 0.5], # X point
42    ]
43
44    multi[1].set_kpath(ndivsm=6, kptbounds=kptbounds)
45    multi[1].set_vars(tolwfr=1e-12)
46
47    # Generate two input files for the GS and the NSCF run
48    scf_input, nscf_input = multi.split_datasets()
49
50    return scf_input, nscf_input
51
52
53def build_flow(options):
54    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
55    if not options.workdir:
56        options.workdir = os.path.basename(sys.argv[0]).replace(".py", "").replace("run_", "flow_")
57
58    # build the structures
59    base_structure = abilab.Structure.from_file(data.cif_file("si.cif"))
60    modifier = abilab.StructureModifier(base_structure)
61
62    etas = [-0.1, 0, +0.1]
63    ph_displ = np.reshape(np.zeros(3*len(base_structure)), (-1,3))
64    ph_displ[0,:] = [+1, 0, 0]
65    ph_displ[1,:] = [-1, 0, 0]
66
67    displaced_structures = modifier.displace(ph_displ, etas, frac_coords=False)
68
69    flow = flowtk.Flow(options.workdir, manager=options.manager)
70
71    for structure in displaced_structures:
72        # Create the work for the band structure calculation.
73        scf_input, nscf_input = make_scf_nscf_inputs(structure)
74
75        work = flowtk.BandStructureWork(scf_input, nscf_input)
76        flow.register_work(work)
77
78    return flow
79
80
81# This block generates the thumbnails in the AbiPy gallery.
82# You can safely REMOVE this part if you are using this script for production runs.
83if os.getenv("READTHEDOCS", False):
84    __name__ = None
85    import tempfile
86    options = flowtk.build_flow_main_parser().parse_args(["-w", tempfile.mkdtemp()])
87    build_flow(options).graphviz_imshow()
88
89
90@flowtk.flow_main
91def main(options):
92    """
93    This is our main function that will be invoked by the script.
94    flow_main is a decorator implementing the command line interface.
95    Command line args are stored in `options`.
96    """
97    return build_flow(options)
98
99
100if __name__ == "__main__":
101    sys.exit(main())
102
103
104############################################################################
105#
106# Run the script with:
107#
108#     run_phfrozen_ebands -s
109#
110# then use:
111#
112#    abirun.py flow_phfrozen_ebands/ structures -v
113#
114# to analyze the input/output structures including the atomic positions:
115#
116# .. code-block:: bash
117#
118#       Lattice parameters:
119#                 formula  natom  angle0  angle1  angle2      a      b      c  volume  \
120#       w0_t0_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
121#       w0_t0_out     Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
122#       w0_t1_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
123#       w1_t0_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
124#       w1_t0_out     Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
125#       w1_t1_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
126#       w2_t0_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
127#       w2_t0_out     Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
128#       w2_t1_in      Si2      2    60.0    60.0    60.0  3.867  3.867  3.867  40.888
129#
130#                 abispg_num  P [GPa]  Max|F| eV/ang task_class              status
131#       w0_t0_in        None      NaN            NaN    ScfTask  Completed
132#       w0_t0_out         12   -3.638      3.180e+00    ScfTask  Completed
133#       w0_t1_in        None      NaN            NaN   NscfTask  Completed
134#       w1_t0_in        None      NaN            NaN    ScfTask  Completed
135#       w1_t0_out        227   -5.212      7.430e-27    ScfTask  Completed
136#       w1_t1_in        None      NaN            NaN   NscfTask  Completed
137#       w2_t0_in        None      NaN            NaN    ScfTask  Completed
138#       w2_t0_out         12   -4.192      2.095e+00    ScfTask  Completed
139#       w2_t1_in        None      NaN            NaN   NscfTask  Completed
140#
141#       Atomic positions (columns give the site index):
142#                                                    0  \
143#       w0_t0_in   (Si, +0.970139 +0.000000 +0.014930)
144#       w0_t0_out  (Si, +0.970139 +0.000000 +0.014930)
145#       w0_t1_in   (Si, +0.970139 +0.000000 +0.014930)
146#       w1_t0_in   (Si, +0.000000 +0.000000 +0.000000)
147#       w1_t0_out  (Si, +0.000000 +0.000000 +0.000000)
148#       w1_t1_in   (Si, +0.000000 +0.000000 +0.000000)
149#       w2_t0_in   (Si, +0.029861 +0.000000 +0.985070)
150#       w2_t0_out  (Si, +0.029861 +0.000000 +0.985070)
151#       w2_t1_in   (Si, +0.029861 +0.000000 +0.985070)
152#
153#                                                    1              status
154#       w0_t0_in   (Si, +0.279861 +0.250000 +0.235070)  Completed
155#       w0_t0_out  (Si, +0.279861 +0.250000 +0.235070)  Completed
156#       w0_t1_in   (Si, +0.279861 +0.250000 +0.235070)  Completed
157#       w1_t0_in   (Si, +0.250000 +0.250000 +0.250000)  Completed
158#       w1_t0_out  (Si, +0.250000 +0.250000 +0.250000)  Completed
159#       w1_t1_in   (Si, +0.250000 +0.250000 +0.250000)  Completed
160#       w2_t0_in   (Si, +0.220139 +0.250000 +0.264930)  Completed
161#       w2_t0_out  (Si, +0.220139 +0.250000 +0.264930)  Completed
162#       w2_t1_in   (Si, +0.220139 +0.250000 +0.264930)  Completed
163#
164#  Finally, we can plot the electronic bands with the command:
165#
166#    abirun.py flow_phfrozen_ebands ebands -p -t NscfTask
167#
168#  to select only the band structures produced by the NscfTask.
169#
170# .. image:: https://github.com/abinit/abipy_assets/blob/master/run_phfrozen_ebands.png?raw=true
171#    :alt: Band structures of Si computed for different displacement amplitudes.
172#
173