Beispiel #1
0
def make_workflow(structure, pseudos, paral_kgb=1):
    """
    Return a `Workflow` object defining a band structure calculation
    for given `Structure`.
    """

    # GS + NSCF run
    multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2)
    nval = structure.num_valence_electrons(pseudos)

    # Variables global to the SCF and the NSCF run.
    multi.set_vars(
        ecut=15,
        paral_kgb=paral_kgb,
        nband=nval//2 + 4,      # occupied + 4 empty
    )

    # (GS run)
    multi[0].set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0])
    multi[0].set_vars(tolvrs=1e-6)

    # (NSCF run)
    multi[1].set_vars(
        iscf=-2,
        tolwfr=1e-12,
    )
    multi[1].set_kpath(ndivsm=8)

    gs_inp, nscf_inp = multi.split_datasets()
    return flowtk.BandStructureWork(gs_inp, nscf_inp)
Beispiel #2
0
def build_flow(options):
    gs_inp, nscf_inp, ddk_inp = make_inputs()

    flow = BenchmarkFlow(workdir=options.get_workdir(__file__),
                         remove=options.remove)

    ebands_work = flowtk.BandStructureWork(gs_inp, nscf_inp)
    flow.register_work(ebands_work)
    flow.exclude_from_benchmark(ebands_work)

    # Get the list of possible parallel configurations from abinit autoparal.
    max_ncpus, min_eff = options.max_ncpus, options.min_eff
    print("Getting all autoparal confs up to max_ncpus: ", max_ncpus,
          " with efficiency >= ", min_eff)

    pconfs = ddk_inp.abiget_autoparal_pconfs(max_ncpus, autoparal=1)
    if options.verbose: print(pconfs)

    work = flowtk.Work()
    for conf, omp_threads in product(pconfs, options.omp_list):
        mpi_procs = conf.mpi_ncpus
        if not options.accept_conf(conf, omp_threads): continue

        manager = options.manager.new_with_fixed_mpi_omp(
            mpi_procs, omp_threads)
        inp = ddk_inp.new_with_vars(conf.vars)
        work.register_ddk_task(inp,
                               manager=manager,
                               deps={ebands_work[1]: "WFK"})

    print("Found %d configurations" % len(work))
    flow.register_work(work)

    return flow.allocate()
Beispiel #3
0
def build_flow(options):
    """
    Build an `AbinitWorkflow` used for benchmarking ABINIT.
    """
    gs_inp, nscf_inp, scr_inp = make_inputs(paw=options.paw)
    flow = BenchmarkFlow(workdir=options.get_workdir(__file__), remove=options.remove)

    bands = flowtk.BandStructureWork(gs_inp, nscf_inp)
    flow.register_work(bands)
    flow.exclude_from_benchmark(bands)

    #for nband in [200, 400, 600]:
    for nband in [600]:
        scr_work = flowtk.Work()
        inp = scr_inp.new_with_vars(nband=nband)
        mpi_list = options.mpi_list
        if mpi_list is None:
            # Cannot call autoparal here because we need a WFK file.
            print("Using hard coded values for mpi_list")
            mpi_list = [np for np in range(1, nband+1) if abs((nband - 4) % np) < 1]
        if options.verbose: print("Using nband %d and mpi_list: %s" % (nband, mpi_list))

        for mpi_procs, omp_threads in product(mpi_list, options.omp_list):
            if not options.accept_mpi_omp(mpi_procs, omp_threads): continue
            manager = options.manager.new_with_fixed_mpi_omp(mpi_procs, omp_threads)
            scr_work.register_scr_task(inp, manager=manager, deps={bands.nscf_task: "WFK"})

        flow.register_work(scr_work)

    return flow.allocate()
Beispiel #4
0
def build_flow(options):

    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    workdir = options.workdir
    if not options.workdir:
        workdir = os.path.basename(__file__).replace(".py", "").replace(
            "run_", "flow_")

    # Initialize structure and pseudos.
    structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
    pseudos = abidata.pseudos("14si.pspnc")

    # Initialize the flow.
    flow = flowtk.Flow(workdir=workdir,
                       manager=options.manager,
                       remove=options.remove)

    # Use ebands_input factory function to build inputs.
    multi = abilab.ebands_input(structure,
                                pseudos,
                                kppa=40,
                                nscf_nband=6,
                                ndivsm=10,
                                ecut=6)
    work = flowtk.BandStructureWork(scf_input=multi[0], nscf_input=multi[1])

    flow.register_work(work)
    return flow
Beispiel #5
0
def make_workflow(structure, pseudos, paral_kgb=1):
    """
    Return a `Workflow` object defining a band structure calculation
    for given `Structure`.
    """
    # Variables global to the SCF and the NSCF run.
    global_vars = dict(
        ecut=abilab.FloatWithUnit(100, "eV").to("Ha"),
        paral_kgb=paral_kgb,
        #nband=8,
    )

    # GS + NSCF run
    multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2)
    multi.set_vars(global_vars)

    # (GS run)
    multi[0].set_kmesh(ngkpt=[8, 8, 8], shiftk=[0, 0, 0])
    multi[0].set_vars(tolvrs=1e-6)

    # (NSCF run)
    multi[1].set_vars(
        iscf=-2,
        tolwfr=1e-12,
        kptopt=0,
        nkpt=1,
        kpt=[0, 0, 0],
    )

    gs_inp, nscf_inp = multi.split_datasets()

    return flowtk.BandStructureWork(gs_inp, nscf_inp)
Beispiel #6
0
def test_scf():
    atoms = build_structure(name='BaTiO3', mag='PM')
    scf_inp = make_scf_input(atoms, spin_mode='unpolarized',is_metal=False)
    ebands_inp = ebands_from_gsinput(scf_inp)

    dos_inp = dos_from_gsinput(scf_inp, dos_kppa=400)

    #scf_task = flowapi.ScfTask(scf_inp)
    #ebands_task = flowapi.NscfTask(ebands_inp)
    #dos_task = flowapi.NscfTask(dos_inp)
    band_work = flowapi.BandStructureWork(
        scf_inp, ebands_inp, dos_inp, workdir=None)

    #phonon_work=flowapi.PhononWork()
    #phonon_work.from_scf_input()

    flow = flowapi.Flow('BaTiO3_scf')
    flow.register_work(band_work)
    #flow.build_and_pickle_dump()
    #flow.plot_networkx()
    #flow.show_status()
    #flow.make_scheduler().start()

    flow_phbands = flowapi.PhononFlow.from_scf_input(
    'BaTiO3_phonon', scf_inp, ph_ngqpt=(2, 2, 2), with_becs=True)
    flow_phbands.make_scheduler().start()
    flow_phbands.show_summary()
Beispiel #7
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        if os.getenv("READTHEDOCS", False):
            __file__ = os.path.join(os.getcwd(), "run_phfrozen_ebands.py")
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    # build the structures
    base_structure = abilab.Structure.from_file(data.cif_file("si.cif"))
    modifier = abilab.StructureModifier(base_structure)

    etas = [-0.1, 0, +0.1]
    ph_displ = np.reshape(np.zeros(3 * len(base_structure)), (-1, 3))
    ph_displ[0, :] = [+1, 0, 0]
    ph_displ[1, :] = [-1, 0, 0]

    displaced_structures = modifier.displace(ph_displ, etas, frac_coords=False)

    flow = flowtk.Flow(options.workdir, manager=options.manager)

    for structure in displaced_structures:
        # Create the work for the band structure calculation.
        scf_input, nscf_input = make_scf_nscf_inputs(structure)

        work = flowtk.BandStructureWork(scf_input, nscf_input)
        flow.register_work(work)

    return flow
Beispiel #8
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        if os.getenv("READTHEDOCS", False):
            __file__ = os.path.join(os.getcwd(), "run_ht_si_ebands.py")
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    # Initialize structure and pseudos.
    structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
    pseudos = abidata.pseudos("14si.pspnc")

    # Initialize the flow.
    flow = flowtk.Flow(workdir=options.workdir, manager=options.manager)

    # Use the ebands_input factory function to build a MultiDataset.
    # keyword args are optional (default values are given or computed automatically, see docs).
    multi = abilab.ebands_input(structure,
                                pseudos,
                                kppa=40,
                                dos_kppa=80,
                                nscf_nband=6,
                                ndivsm=10,
                                ecut=6,
                                spin_mode="unpolarized")

    work = flowtk.BandStructureWork(scf_input=multi[0],
                                    nscf_input=multi[1],
                                    dos_inputs=multi[2])
    flow.register_work(work)

    return flow
Beispiel #9
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    flow = flowtk.Flow(workdir=options.workdir, manager=options.manager)

    for nspinor in (1, 2):
        #for nspinor in (2,):
        # Get our templates
        scf_inp, bands_inp, nscf_inp, scr_inp, sig_inp = make_inputs(nspinor)

        # Band structure work to produce the WFK file
        bands_work = flowtk.BandStructureWork(scf_inp,
                                              bands_inp,
                                              dos_inputs=[nscf_inp])
        flow.register_work(bands_work)

        # Build a work made of two SCR runs with different value of nband
        gw_work = flowtk.Work()
        scr_task = gw_work.register_scr_task(scr_inp,
                                             deps={bands_work[2]: "WFK"})
        gw_work.register_sigma_task(sig_inp,
                                    deps={
                                        bands_work[2]: "WFK",
                                        scr_task: "SCR"
                                    })
        flow.register_work(gw_work)

    return flow
Beispiel #10
0
def itest_flow_without_runnable_tasks(fwp):
    """
    Test the behaviour of the scheduler when we ignore errrors and
    all the task that can be executed have been submitted.
    The scheduler should detect this condition and exit.
    """
    # Get the SCF and the NSCF input.
    scf_input, nscf_input = make_scf_nscf_inputs()

    # Build the flow.
    flow = flowtk.Flow(fwp.workdir, manager=fwp.manager)
    work0 = flowtk.BandStructureWork(scf_input, nscf_input)
    flow.register_work(work0)
    scf_task, nscf_task = work0.scf_task, work0.nscf_task

    flow.allocate()

    # Mock an Errored nscf_task. This will cause a deadlock in the flow.
    nscf_task = mocks.change_task_start(nscf_task)

    sched = flow.make_scheduler()
    sched.max_num_abierrs = 10000
    assert sched.start() == 0
    flow.check_status(show=True)

    assert not flow.all_ok
    assert scf_task.status == scf_task.S_OK
    assert nscf_task.status == nscf_task.S_ERROR

    g = flow.find_deadlocks()
    assert not g.deadlocked and not g.runnables and not g.running
Beispiel #11
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    flow = flowtk.Flow(options.workdir, manager=options.manager)

    # Create the work for the band structure calculation.
    structure = abidata.structure_from_ucell("NiO")
    pseudos = abidata.pseudos("28ni.paw", "8o.2.paw")

    # The code below set up the parameters for the LDA+U calculation in NiO.
    #usepawu   1
    #lpawu   2 -1
    #upawu  8.0 0.0 eV
    #jpawu  0.8 0.0 eV
    usepawu = 1
    u_values = [5.0, 8.0]

    for u in u_values:
        # Apply U-J on Ni only.
        luj_params = LdauParams(usepawu, structure)
        luj_params.luj_for_symbol("Ni", l=2, u=u, j=0.1 * u, unit="eV")

        scf_input, nscf_input, dos_input = make_scf_nscf_dos_inputs(
            structure, pseudos, luj_params)

        work = flowtk.BandStructureWork(scf_input,
                                        nscf_input,
                                        dos_inputs=dos_input)
        flow.register_work(work)

    return flow
Beispiel #12
0
def itest_htc_bandstructure(fwp, tvars):
    """Test band-structure calculations done with the HTC interface."""
    structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
    pseudos = abidata.pseudos("14si.pspnc")

    # Initialize the flow.
    flow = abilab.Flow(workdir=fwp.workdir, manager=fwp.manager)

    # Use ebands_input factory function to build inputs.
    multi = abilab.ebands_input(structure,
                                pseudos,
                                kppa=20,
                                nscf_nband=6,
                                ndivsm=5,
                                ecut=2,
                                dos_kppa=40,
                                spin_mode="unpolarized")

    work = flowtk.BandStructureWork(scf_input=multi[0],
                                    nscf_input=multi[1],
                                    dos_inputs=multi[2:])
    multi.set_vars(paral_kgb=tvars.paral_kgb)

    flow.register_work(work)
    flow.allocate()
    flow.build_and_pickle_dump(abivalidate=True)

    fwp.scheduler.add_flow(flow)
    assert fwp.scheduler.start() == 0
    assert not fwp.scheduler.exceptions
    assert fwp.scheduler.nlaunch == 3

    flow.show_status()
    if not flow.all_ok:
        flow.debug()
        raise RuntimeError()

    assert all(work.finalized for work in flow)

    # Test if GSR files are produced and are readable.
    for i, task in enumerate(work):
        with task.open_gsr() as gsr:
            assert gsr.nsppol == 1
            #assert gsr.structure == structure
            if i == 0:
                gsr.to_string(verbose=2)

            if i == 1:
                # Bandstructure case
                assert gsr.ebands.has_bzpath
                assert not gsr.ebands.has_bzmesh
                with pytest.raises(ValueError):
                    gsr.ebands.get_edos()

            if i == 2:
                # DOS case
                assert gsr.ebands.has_bzmesh
                assert not gsr.ebands.has_bzpath
                gsr.ebands.get_edos()
def build_flow(options):
    # Set working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        options.workdir = os.path.basename(sys.argv[0]).replace(".py", "").replace("run_", "flow_")

    structure = abidata.structure_from_ucell("GaAs")
    pseudos = abidata.pseudos("Ga-low_r.psp8", "As_r.psp8")
    num_electrons = structure.num_valence_electrons(pseudos)
    #print("num_electrons:", num_electrons)

    # Usa same shifts in all tasks.
    ngkpt = [4, 4, 4]
    shiftk = [
        [0.5, 0.5, 0.5],
        [0.5, 0.0, 0.0],
        [0.0, 0.5, 0.0],
        [0.0, 0.0, 0.5],
    ]

    # NSCF run on k-path with large number of bands
    kptbounds = [
        [0.5, 0.0, 0.0],  # L point
        [0.0, 0.0, 0.0],  # Gamma point
        [0.0, 0.5, 0.5],  # X point
    ]

    # Initialize the flow.
    flow = flowtk.Flow(options.workdir, manager=options.manager)

    for nspinor in [1, 2]:
        # Multi will contain two datasets (GS + NSCF) for the given nspinor.
        multi = abilab.MultiDataset(structure=structure, pseudos=pseudos, ndtset=2)

        # Global variables.
        multi.set_vars(
            ecut=20,
            nspinor=nspinor,
            nspden=1 if nspinor == 1 else 4,
            so_psp="*0" if nspinor == 1 else "*1",   # Important!
            #paral_kgb=1,
        )

        nband_occ = num_electrons // 2 if nspinor == 1 else num_electrons
        #print(nband_occ)

        # Dataset 1 (GS run)
        multi[0].set_vars(tolvrs=1e-8, nband=nband_occ + 4)
        multi[0].set_kmesh(ngkpt=ngkpt, shiftk=shiftk, kptopt=1 if nspinor == 1 else 4)

        multi[1].set_vars(iscf=-2, nband=nband_occ + 4, tolwfr=1.e-12)
        multi[1].set_kpath(ndivsm=10, kptbounds=kptbounds)

        # Get the SCF and the NSCF input.
        scf_input, nscf_input = multi.split_datasets()

        flow.register_work(flowtk.BandStructureWork(scf_input, nscf_input))

    return flow
Beispiel #14
0
def itest_flow_with_deadlocks(fwp):
    """
    Test the behaviour of the scheduler in the presence of a deadlock
    when we ignore errored tasks and we try to run all tasks in the flow.
    The scheduler should detect the deadlock and exit when no other task can be executed.
    """
    # Get the SCF and the NSCF input.
    scf_input, nscf_input = make_scf_nscf_inputs()

    # Build the flow.
    flow = flowtk.Flow(fwp.workdir, manager=fwp.manager)
    work0 = flowtk.BandStructureWork(scf_input,
                                     nscf_input,
                                     dos_inputs=nscf_input)
    flow.register_work(work0)
    scf_task, nscf_task, dos_task = work0[0], work0[1], work0[2]

    work1 = flowtk.Work()
    work1.register_nscf_task(nscf_input,
                             deps={
                                 scf_task: "DEN",
                                 dos_task: "WFK"
                             })
    # This task will deadlock when nscf_task reaches S_ERROR.
    work1.register_nscf_task(nscf_input,
                             deps={
                                 scf_task: "DEN",
                                 nscf_task: "WFK"
                             })
    flow.register_work(work1)

    flow.allocate()

    # Mock an Errored nscf_task. This will cause a deadlock in the flow.
    nscf_task = mocks.change_task_start(nscf_task)

    # Here we set max_num_abierrs to a very large number.
    sched = flow.make_scheduler()
    sched.max_num_abierrs = 10000
    assert sched.start() == 0
    flow.check_status(show=True)

    assert not flow.all_ok
    assert all(task.status == task.S_OK
               for task in [scf_task, dos_task, work1[0]])
    assert all(task.status == task.S_ERROR for task in [nscf_task])
    g = flow.find_deadlocks()
    assert g.deadlocked and not g.runnables and not g.running
    assert work1[1] in g.deadlocked
Beispiel #15
0
def build_g0w0_flow(options=None, ngkpt=(2, 2, 2)):
    """
    Build and return a flow with two works.
    The first work is a standard KS band-structure calculation that consists of
    an initial GS calculation to get the density followed by two NSCF calculations.

    The first NSCF task computes the KS eigenvalues on a high-symmetry path in the BZ,
    whereas the second NSCF task employs a homogeneous k-mesh so that one can compute
    the DOS from the KS eigenvalues.

    The second work represents the real GW workflow that uses the density computed in the first task of
    the previous work  to compute the KS bands for many empty states.
    The WFK file produced in this step is then used to compute the screened interaction $W$.
    Finally, we perform a self-energy calculation that uses the $W$ produced
    in the previous step and the WFK file to compute the matrix elements of the self-energy and
    the $G_0W_0$ corrections for all the k-points in the IBZ and 8 bands (4 occupied + 4 empty)
    """

    # Call make_input to build our 4 input objects.
    scf, bands_nscf, dos_nscf, gw_nscf, scr, sig = make_inputs(ngkpt=ngkpt)

    workdir = options.workdir if (options and options.workdir) else "flow_g0w0"
    flow = flowtk.Flow(workdir=workdir)

    # Add KS band structure work (SCF-GS followed by two NSCF runs
    # (the first one is done on a k-path, the second on the IBZ to compute the DOS
    work0 = flowtk.BandStructureWork(scf, bands_nscf, dos_inputs=dos_nscf)
    flow.register_work(work0)

    # Create new Work for GW
    work1 = flowtk.Work()

    # NSCF run with empty states
    gw_nscf_task = work1.register_nscf_task(gw_nscf, deps={work0[0]: "DEN"})

    # SCR run with WFK produced by previous task.
    scr_task = work1.register_scr_task(scr, deps={gw_nscf_task: "WFK"})

    # SIGMA task (requires WFK with empty states and SCR file)
    sigma_task = work1.register_sigma_task(sig,
                                           deps={
                                               gw_nscf_task: "WFK",
                                               scr_task: "SCR"
                                           })

    # Add GW work to flow.
    flow.register_work(work1)

    return flow
Beispiel #16
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        options.workdir = os.path.basename(__file__).replace(".py", "").replace("run_","flow_")

    # Create the Flow.
    flow = flowtk.Flow(options.workdir, manager=options.manager)

    # Create the task defining the calculation and run and register it in the flow
    for nsppol in [1, 2]:
        scf_input, nscf_input = make_scf_nscf_inputs(nsppol)
        work = flowtk.BandStructureWork(scf_input, nscf_input)
        flow.register_work(work)

    return flow
Beispiel #17
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        if os.getenv("READTHEDOCS", False):
            __file__ = os.path.join(os.getcwd(), "run_relax_and_ebands.py")
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    # Create the flow
    flow = flowtk.Flow(options.workdir, manager=options.manager)

    paral_kgb = 1
    #paral_kgb = 0  # This one is OK

    # Create a relaxation work and add it to the flow.
    ion_inp, ioncell_inp = make_ion_ioncell_inputs(paral_kgb=paral_kgb)

    relax_work = flowtk.RelaxWork(ion_inp, ioncell_inp)
    flow.register_work(relax_work)

    scf_inp, nscf_inp = make_scf_nscf_inputs(paral_kgb=paral_kgb)

    bands_work = flowtk.BandStructureWork(scf_inp, nscf_inp)

    # The scf task in bands work restarts from the DEN file of the last task in relax_work
    if paral_kgb == 0:
        # cg works fine if we restart from the WFK
        bands_work.scf_task.add_deps({relax_work[-1]: "WFK"})
    else:
        # --> This triggers an infamous bug in abinit
        bands_work.scf_task.add_deps({relax_work[-1]: "WFK"})

        # --> This is ok if we used fourier_interp to change the FFT mesh.
        #bands_work.scf_task.add_deps({relax_work[-1]: "DEN"})

    # All task in bands_work will fetch the relaxed structure from the last task in relax_work
    for task in bands_work:
        task.add_deps({relax_work[-1]: "@structure"})

    flow.register_work(bands_work)
    flow.allocate()
    flow.use_smartio()
    flow.set_garbage_collector()

    return flow
Beispiel #18
0
def build_flow(options):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        if os.getenv("READTHEDOCS", False):
            __file__ = os.path.join(os.getcwd(), "run_gwconv_ecuteps.py")
        options.workdir = os.path.basename(__file__).replace(
            ".py", "").replace("run_", "flow_")

    # Get our templates
    scf_inp, nscf_inp, scr_inp, sig_inp = make_inputs()

    ecuteps_list = np.arange(2, 8, 2)
    max_ecuteps = max(ecuteps_list)

    flow = flowtk.Flow(workdir=options.workdir, manager=options.manager)

    # Band structure work to produce the WFK file
    bands = flowtk.BandStructureWork(scf_inp, nscf_inp)
    flow.register_work(bands)

    # Build a work made of two SCR runs with different value of nband
    # Use max_ecuteps for the dielectric matrix (sigma tasks will
    # read a submatrix when we test the convergence wrt to ecuteps.
    scr_work = flowtk.Work()

    for inp in scr_inp.generate(nband=[10, 15]):
        inp.set_vars(ecuteps=max_ecuteps)
        scr_work.register_scr_task(inp, deps={bands.nscf_task: "WFK"})

    flow.register_work(scr_work)

    # Do a convergence study wrt ecuteps, each work is connected to a
    # different SCR file computed with a different value of nband.

    # Build a list of sigma inputs with different ecuteps
    sigma_inputs = list(sig_inp.generate(ecuteps=ecuteps_list))

    for scr_task in scr_work:
        sigma_conv = flowtk.SigmaConvWork(wfk_node=bands.nscf_task,
                                          scr_node=scr_task,
                                          sigma_inputs=sigma_inputs)
        flow.register_work(sigma_conv)

    return flow
Beispiel #19
0
def make_g0w0_scissors_flow(workdir="flow_lesson_g0w0", ngkpt=(2, 2, 2)):
    # Change the value of ngkpt below to perform a GW calculation with a different k-mesh.
    scf, bands_nscf, dos_nscf, gw_nscf, scr, sig = make_inputs(ngkpt=ngkpt)

    flow = flowtk.Flow(workdir=workdir)
    work0 = flowtk.BandStructureWork(scf, bands_nscf, dos_inputs=dos_nscf)
    flow.register_work(work0)

    work1 = flowtk.Work()
    gw_nscf_task = work1.register_nscf_task(gw_nscf, deps={work0[0]: "DEN"})
    scr_task = work1.register_scr_task(scr, deps={gw_nscf_task: "WFK"})
    sigma_task = work1.register_sigma_task(sig,
                                           deps={
                                               gw_nscf_task: "WFK",
                                               scr_task: "SCR"
                                           })
    flow.register_work(work1)

    return flow.allocate()
Beispiel #20
0
def itest_htc_bandstructure(fwp, tvars):
    """Test band-structure calculations done with the HTC interface."""
    structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
    pseudos = abidata.pseudos("14si.pspnc")

    # TODO: Add this options because I don't like the kppa approach
    # I had to use it because it was the approach used in VaspIO
    #dos_ngkpt = [4,4,4]
    #dos_shiftk = [0.1, 0.2, 0.3]

    # Initialize the flow.
    flow = abilab.Flow(workdir=fwp.workdir, manager=fwp.manager)

    # Use ebands_input factory function to build inputs.
    multi = abilab.ebands_input(structure,
                                pseudos,
                                kppa=20,
                                nscf_nband=6,
                                ndivsm=5,
                                ecut=2,
                                dos_kppa=40,
                                spin_mode="unpolarized")

    work = flowtk.BandStructureWork(scf_input=multi[0],
                                    nscf_input=multi[1],
                                    dos_inputs=multi[2:])
    multi.set_vars(paral_kgb=tvars.paral_kgb)

    flow.register_work(work)
    flow.allocate()
    flow.build_and_pickle_dump(abivalidate=True)

    fwp.scheduler.add_flow(flow)
    assert fwp.scheduler.start() == 0
    assert not fwp.scheduler.exceptions
    assert fwp.scheduler.nlaunch == 3

    flow.show_status()
    assert flow.all_ok
    assert all(work.finalized for work in flow)

    # Test if GSR files are produced and are readable.
    for i, task in enumerate(work):
        with task.open_gsr() as gsr:
            print(gsr)
            assert gsr.nsppol == 1
            #assert gsr.structure == structure
            ebands = gsr.ebands

            # TODO: This does not work yet because GSR files do not contain
            # enough info to understand if we have a path or a mesh.
            #if i == 2:
            # Bandstructure case
            #assert ebands.has_bzpath
            #with pytest.raises(ebands.Error):
            #    ebands.get_edos()

            if i == 3:
                # DOS case
                assert ebands.has_bzmesh
                gsr.bands.get_edos()
Beispiel #21
0
def build_flow(options):
    """
    C in diamond structure. Very rough q-point mesh, low ecut, completely unconverged.
    The flow computes the ground state density and a WFK file on a 8x8x8 k-mesh including
    empty states needed for the self-energy. Then all the independent atomic perturbations
    for the irreducible qpoints in a 4x4x4 grid are obtained with DFPT.
    Finally, we enter the EPH driver to compute the EPH self-energy.
    """
    workdir = options.workdir if (options and options.workdir) else "flow_diamond"

    # Define structure explicitly.
    structure = abilab.Structure.from_abivars(
        acell=3*[6.70346805],
        rprim=[0.0, 0.5, 0.5,
               0.5, 0.0, 0.5,
               0.5, 0.5, 0.0],
        typat=[1, 1],
        xred=[0.0, 0.0, 0.0, 0.25, 0.25, 0.25],
        ntypat=1,
        znucl=6,
    )

    # Initialize input from structure and norm-conserving pseudo provided by AbiPy.
    gs_inp = abilab.AbinitInput(structure, pseudos=abidata.pseudos("C.oncvpsp"))

    # Set basic variables for GS part.
    gs_inp.set_vars(
        istwfk="*1",
        ecut=20.0,
        nband=4,
        tolvrs=1e-10,
    )

    # The kpoint grid is minimalistic to keep the calculation manageable.
    # The q-mesh for phonons must be a submesh of this one.
    gs_inp.set_kmesh(
        ngkpt=[8, 8, 8],
        shiftk=[0.0, 0.0, 0.0],
    )

    # Build new input for NSCF calculation with k-path (automatically selected by AbiPy)
    # Used to plot the KS band structure and interpolate the QP corrections.
    nscf_kpath_inp = gs_inp.new_with_vars(
        nband=8,
        tolwfr=1e-16,
        iscf=-2,
    )
    nscf_kpath_inp.set_kpath(ndivsm=10)

    # Build another NSCF input with k-mesh and empty states.
    # This step generates the WFK file used to build the EPH self-energy.
    nscf_empty_kmesh_inp = gs_inp.new_with_vars(
        #nband=210,
        nband=110,
        nbdbuf=10,      # nbdbuf reduces considerably the time needed
        tolwfr=1e-16,   # to converge so many empty states!
        iscf=-2,
    )

    # Create empty flow.
    flow = flowtk.Flow(workdir=workdir)

    # Register GS + band structure parts in the first work
    work0 = flowtk.BandStructureWork(gs_inp, nscf_kpath_inp, dos_inputs=[nscf_empty_kmesh_inp])
    flow.register_work(work0)

    # Generate Phonon work with 4x4x4 q-mesh
    # Reuse variables from GS input and let AbiPy handle the generation of the input files
    # Note that the q-point grid is a sub-grid of the k-point grid (here 8x8x8)
    ddb_ngqpt = [4, 4, 4]
    ph_work = flowtk.PhononWork.from_scf_task(work0[0], ddb_ngqpt, is_ngqpt=True)
    flow.register_work(ph_work)

    # Build input for E-PH run. See also v8/Input/t44.in
    # Matrix elements of self-energy are computed for 2 k-points and the first 8 bands.
    # The k-points must be in the WFK file

    eph_inp = gs_inp.new_with_vars(
        optdriver=7,               # Enter EPH driver.
        eph_task=4,                # Activate computation of EPH self-energy.
        ddb_ngqpt=ddb_ngqpt,       # q-mesh used to produce the DDB file (must be consistent with DDB data)
        nband=54,
        symsigma=0,
        nkptgw=2,
        kptgw=[0, 0, 0,
               0.5, 0, 0],
        bdgw=[1, 8, 1, 8],
        #eph_intmeth=2,            # Tetra method
        #gw_qprange-2
        #tmesh=[10, 1000, 5],
        #gw_qprange=-4,
    )

    # Set q-path for Fourier interpolation of phonons.
    eph_inp.set_qpath(10)

    # Set q-mesh for phonons DOS.
    eph_inp.set_phdos_qmesh(nqsmall=16, method="tetra")

    # EPH part requires the GS WFK, the DDB file with all perturbations
    # and the database of DFPT potentials (already merged by PhononWork)
    deps = {work0[2]: "WFK", ph_work: ["DDB", "DVDB"]}

    # Now we use the EPH template generated above to perform a convergence study
    # by varying the q-mesh used to integrate the self-energy and the number of bands
    # The code will activate the Fourier interpolation of the DFPT potentials if eph_ngqpt_fine != ddb_ngqpt

    for eph_ngqpt_fine in [[4, 4, 4], [8, 8, 8]]:
        eph_work = flow.register_work(flowtk.Work())
        for nband in [25, 50, 75, 100]:
            new_inp = eph_inp.new_with_vars(eph_ngqpt_fine=eph_ngqpt_fine, nband=nband)
            eph_work.register_eph_task(new_inp, deps=deps)

    flow.allocate()

    return flow
Beispiel #22
0
def build_flow(options):
    """
    Build and return an AbiPy flow to compute phonon linewidths and Eliashberg function in Aluminium:

        1. Compute DFPT phonons on a 4x4x4 q-mesh with a coarse 8x8x8 k-sampling

        2. Generate 3 WFK files on a much denser k-mesh (x16, x24, x32)

        3. Run the EPH code with:

          - one of the WFK files generated in point 2.
          - interpolated DFPT potentials (from the initial 4x4x4 to a 8x8x8 q-mesh)

        4. Analyze the convergence of the results wrt nkpt.

    Note that the q-point grid must be a sub-grid of the k-point grid
    """
    workdir = options.workdir if (options
                                  and options.workdir) else "flow_eph_al"

    # Create empty flow.
    flow = flowtk.Flow(workdir=workdir)

    # Init structure. Use NC pseudo
    structure = abilab.Structure.fcc(a=7.5, species=["Al"], units="bohr")
    pseudos = abidata.pseudos("Al.oncvpsp")

    # Input for GS part.
    gs_inp = abilab.AbinitInput(structure, pseudos)
    gs_inp.set_vars(
        istwfk="*1",
        ecut=8.0,
        nband=4,
        occopt=7,  # Include metallic occupation function with a small smearing
        tsmear=0.04,
        tolvrs=1e-7,
    )

    # The k-grid is minimalistic to keep the calculation manageable.
    gs_inp.set_kmesh(
        ngkpt=[8, 8, 8],
        shiftk=[0.0, 0.0, 0.0],
    )

    # Build new input for NSCF calculation along k-path (automatically selected by AbiPy)
    # Used to plot the KS band structure.
    nscf_kpath_inp = gs_inp.new_with_vars(
        nband=4,
        tolwfr=1e-16,
        iscf=-2,
    )
    nscf_kpath_inp.set_kpath(ndivsm=10)

    # Build NSCF inputs with denser k-meshes
    # This step generates the WFK files used to compute the Eliashberg function.
    # We have a cubic material so we only need to specify the first number of divisions.
    nk_list = [16, 24, 32]

    nscf_kmesh_inputs = []
    for nk in nk_list:
        new_inp = gs_inp.new_with_vars(
            tolwfr=1e-16,
            iscf=-2,
            ngkpt=[nk] * 3,
            shiftk=[0.0, 0.0, 0.0],
        )
        nscf_kmesh_inputs.append(new_inp)

    # Register GS + NSCF kpath + NSCF with k-meshes in work0.
    work0 = flowtk.BandStructureWork(gs_inp,
                                     nscf_kpath_inp,
                                     dos_inputs=nscf_kmesh_inputs)
    flow.register_work(work0)

    # Generate Phonon work with 4x4x4 q-mesh
    # Reuse the variables from GS input and let AbiPy handle the generation of the input files
    # Note that the q-point grid is a sub-grid of the k-mesh so we do not need WFQ on k+q mesh.
    ddb_ngqpt = [4, 4, 4]
    ph_work = flowtk.PhononWork.from_scf_task(work0[0],
                                              ddb_ngqpt,
                                              is_ngqpt=True)
    flow.register_work(ph_work)

    # Ssction for EPH calculation: compute linewidths with different WKK files.
    eph_work = flowtk.Work()
    for ik, nk in enumerate(nk_list):
        # Each task uses a different WFK file. DDB and DBDB do not change.
        eph_deps = {work0[2 + ik]: "WFK", ph_work: ["DDB", "DVDB"]}

        # Interpolate DFPT potentials 4x4x4 --> 8x8x8
        eph_ngqpt_fine = (8, 8, 8)

        # Build input for E-PH run. See also v7/Input/t85.in
        # The k-points must be in the WFK file
        eph_inp = gs_inp.new_with_vars(
            optdriver=7,  # Enter EPH driver.
            eph_task=1,  # Compute phonon linewidths in metals.
            ddb_ngqpt=
            ddb_ngqpt,  # q-mesh used to produce the DDB file (must be consistent with DDB data)
            eph_fsewin=
            "0.8 eV",  # Energy window around Ef (only states in this window are included)
            eph_intmeth=2,  # Tetra method
            #eph_intmeth=1,                 # Gaussian
            #eph_fsmear=eph_fsmear * abilab.units.eV_to_Ha, # Broadening
            eph_ngqpt_fine=
            eph_ngqpt_fine,  # Interpolate DFPT potentials if != ddb_ngqpt
            eph_mustar=0.12,  # mustar parameter
            ngkpt=[nk] * 3,
            shiftk=[0.0, 0.0, 0.0],
        )

        # Set q-path to interpolate phonons and phonon linewidths.
        eph_inp.set_qpath(10)

        # Set q-mesh for phonons DOS and a2F(w)
        eph_inp.set_phdos_qmesh(nqsmall=24, method="tetra")
        eph_work.register_eph_task(eph_inp, deps=eph_deps)

    flow.register_work(eph_work)

    # Avoid producing (big) output files that not required by children.
    flow.allocate(use_smartio=True)

    return flow
Beispiel #23
0
def make_base_flow(options):
    multi = abilab.MultiDataset(structure=data.structure_from_ucell("GaAs"),
                                pseudos=data.pseudos("31ga.pspnc",
                                                     "33as.pspnc"),
                                ndtset=5)

    # Global variables
    kmesh = dict(ngkpt=[4, 4, 4],
                 nshiftk=4,
                 shiftk=[[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0],
                         [0.0, 0.0, 0.5]])

    paral_kgb = 1
    global_vars = dict(ecut=2, paral_kgb=paral_kgb)
    global_vars.update(kmesh)

    multi.set_vars(global_vars)

    # Dataset 1 (GS run)
    multi[0].set_vars(
        tolvrs=1e-6,
        nband=4,
    )

    # NSCF run with large number of bands, and points in the the full BZ
    multi[1].set_vars(
        iscf=-2,
        nband=20,
        nstep=25,
        kptopt=1,
        tolwfr=1.e-9,
        #kptopt=3,
    )

    # Fourth dataset: ddk response function along axis 1
    # Fifth dataset: ddk response function along axis 2
    # Sixth dataset: ddk response function along axis 3
    for dir in range(3):
        rfdir = 3 * [0]
        rfdir[dir] = 1

        multi[2 + dir].set_vars(
            iscf=-3,
            nband=20,
            nstep=1,
            nline=0,
            prtwf=3,
            kptopt=3,
            nqpt=1,
            qpt=[0.0, 0.0, 0.0],
            rfdir=rfdir,
            rfelfd=2,
            tolwfr=1.e-9,
        )

    scf_inp, nscf_inp, ddk1, ddk2, ddk3 = multi.split_datasets()

    # Initialize the flow.
    flow = BenchmarkFlow(workdir=options.get_workdir(__file__),
                         remove=options.manager)

    bands_work = flowtk.BandStructureWork(scf_inp, nscf_inp)
    flow.register_work(bands_work)
    flow.exclude_from_benchmark(bands_work)

    ddk_work = flowtk.Work()
    for inp in [ddk1, ddk2, ddk3]:
        ddk_work.register_ddk_task(inp, deps={bands_work.nscf_task: "WFK"})

    flow.register_work(ddk_work)
    flow.exclude_from_benchmark(ddk_work)

    return flow
Beispiel #24
0
def build_flow(options):
    """
    C in diamond structure. Very rough q-point mesh, low ecut, completely unconverged.
    The flow compute the ground state density a WFK file on a k-mesh used for DFPT phonons
    a WFK file on a k-mesh with empty states used for the self-energy.
    Then all of the independent perturbations for the irreducible qpoints in a 4x4x4 grid are obtained.
    Note that the q-point grid must be a sub-grid of the k-point grid (here 8x8x8)
    Finally, we enter the EPH driver to compute the Fan-Migdal self-energy.
    """
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    workdir = options.workdir
    if not options.workdir:
        workdir = os.path.basename(__file__).replace(".py", "").replace(
            "run_", "flow_")

    # Define structure explicitly.
    structure = abilab.Structure.from_abivars(
        acell=3 * [6.70346805],
        rprim=[0.0, 0.5, 0.5, 0.5, 0.0, 0.5, 0.5, 0.5, 0.0],
        typat=[1, 1],
        xred=[0.0, 0.0, 0.0, 0.25, 0.25, 0.25],
        ntypat=1,
        znucl=6,
    )

    gs_inp = abilab.AbinitInput(structure,
                                pseudos=abidata.pseudos("C.oncvpsp"))

    gs_inp.set_vars(
        istwfk="*1",
        ecut=12.0,
        nband=4,
        tolvrs=1e-10,
    )

    # The kpoint grid is minimalistic to keep the calculation manageable.
    gs_inp.set_kmesh(
        ngkpt=[4, 4, 4],
        shiftk=[0.0, 0.0, 0.0],
        #kptopt=3,
    )

    # NSCF run with k-path (just for plotting purpose)
    nscf_kpath_inp = gs_inp.new_with_vars(
        nband=8,
        tolwfr=1e-16,
    )
    #nscf_kpath_inp.pop_vars(["tolvrs"])
    nscf_kpath_inp.set_kpath(ndivsm=10)

    # NSCF run with k-mesh to get WFK with empty states.
    nscf_empty_kmesh_inp = gs_inp.new_with_vars(
        nband=54,
        nbdbuf=4,
        tolwfr=1e-16,
        iscf=-2,
    )

    flow = flowtk.Flow(workdir, manager=options.manager, remove=options.remove)

    # GS run to get the WFK
    work0 = flowtk.BandStructureWork(gs_inp,
                                     nscf_kpath_inp,
                                     dos_inputs=[nscf_empty_kmesh_inp])
    flow.register_work(work0)

    # Phonon work with 4x4x4 q-mesh
    ddb_ngqpt = [2, 2, 2]
    ph_work = flowtk.PhononWork.from_scf_task(work0[0],
                                              ddb_ngqpt,
                                              is_ngqpt=True)
    flow.register_work(ph_work)

    # Build input file for E-PH run. See v8/Input/t44.in
    eph_inp = gs_inp.new_with_vars(
        optdriver=7,  # EPH driver.
        eph_task=4,  # For electronic self-energy due to phonon
        nband=54,
        ddb_ngqpt=
        ddb_ngqpt,  # q-mesh used to produce the DDB file (must be consistent with DDB data)
        symsigma=0,
        gw_qprange=2,
        #eph_intmeth=2,            # Tetra method
        #gw_qprange -2
    )

    # Set q-path for phonons and phonon linewidths.
    eph_inp.set_qpath(10)

    # Set q-mesh for phonons DOS.
    eph_inp.set_phdos_qmesh(nqsmall=16, method="tetra")

    # EPH part requires the GS WFK, the DDB file with all perturbations
    # and the database of DFPT potentials (already merged by PhononWork)
    eph_work = flow.register_work(flowtk.Work())
    deps = {work0[2]: "WFK", ph_work: ["DDB", "DVDB"]}

    eph_work.register_eph_task(eph_inp, deps=deps)

    # Activate Fourier interpolation of DFPT potentials.
    eph_work.register_eph_task(eph_inp.new_with_vars(eph_ngqpt_fine=[4, 4, 4]),
                               deps=deps)
    #eph_work.register_eph_task(eph_inp.new_with_vars(eph_ngqpt_fine=[12, 12, 12]), deps=deps)

    flow.allocate()

    return flow
Beispiel #25
0
def build_flow(options):
    """
    C in diamond structure. Very rough q-point mesh, low ecut, completely unconverged.
    The flow computes the ground state density and a WFK file on a 8x8x8 k-mesh including
    empty states needed for the self-energy. Then all the independent atomic perturbations
    for the irreducible qpoints in a 4x4x4 grid are obtained with DFPT.
    Finally, we enter the EPH driver to compute the EPH self-energy.
    """
    workdir = options.workdir if (options
                                  and options.workdir) else "flow_diamond"

    # Define structure explicitly.
    structure = abilab.Structure.from_abivars(
        acell=3 * [6.70346805],
        rprim=[0.0, 0.5, 0.5, 0.5, 0.0, 0.5, 0.5, 0.5, 0.0],
        typat=[1, 1],
        xred=[0.0, 0.0, 0.0, 0.25, 0.25, 0.25],
        ntypat=1,
        znucl=6,
    )

    # Initialize input from structure and norm-conserving pseudo provided by AbiPy.
    gs_inp = abilab.AbinitInput(structure, pseudos="6c.pspnc")

    # Set basic variables for GS part.
    gs_inp.set_vars(
        istwfk="*1",
        ecut=20.0,  # Too low, shout be ~30
        nband=4,
        tolvrs=1e-8,
    )

    # The kpoint grid is minimalistic to keep the calculation manageable.
    # The q-mesh for phonons must be a submesh of this one.
    gs_inp.set_kmesh(
        ngkpt=[8, 8, 8],
        shiftk=[0.0, 0.0, 0.0],
    )

    # Build new input for NSCF calculation with k-path (automatically selected by AbiPy)
    # Used to plot the KS band structure and interpolate the QP corrections.
    nscf_kpath_inp = gs_inp.new_with_vars(
        nband=8,
        tolwfr=1e-16,
        iscf=-2,
    )
    nscf_kpath_inp.set_kpath(ndivsm=10)

    # Build another NSCF input with k-mesh and empty states.
    # This step generates the WFK file used to build the EPH self-energy.
    nscf_empty_kmesh_inp = gs_inp.new_with_vars(
        nband=210,  # Too low. ~300
        nbdbuf=
        10,  # Reduces considerably the time needed to converge empty states!
        tolwfr=1e-16,
        iscf=-2,
    )

    # Create empty flow.
    flow = flowtk.Flow(workdir=workdir)

    # Register GS + band structure parts in the first work
    work0 = flowtk.BandStructureWork(gs_inp,
                                     nscf_kpath_inp,
                                     dos_inputs=[nscf_empty_kmesh_inp])
    flow.register_work(work0)

    # Generate Phonon work with 4x4x4 q-mesh
    # Reuse variables from GS input and let AbiPy handle the generation of the input files
    # Note that the q-point grid is a sub-grid of the k-point grid (here 8x8x8)
    ddb_ngqpt = [4, 4, 4]
    ph_work = flowtk.PhononWork.from_scf_task(
        work0[0], ddb_ngqpt, is_ngqpt=True,
        tolerance={"tolvrs": 1e-6})  # This to speedup DFPT
    flow.register_work(ph_work)

    # Build template for self-energy calculation. See also v8/Input/t44.in
    # The k-points must be in the WFK file
    #
    eph_inp = gs_inp.new_with_vars(
        optdriver=7,  # Enter EPH driver.
        eph_task=4,  # Activate computation of EPH self-energy.
        ddb_ngqpt=
        ddb_ngqpt,  # q-mesh used to produce the DDB file (must be consistent with DDB data)
        symsigma=
        1,  # Use symmetries in self-energy integration (IBZ_k instead of BZ)
        nkptgw=1,
        kptgw=[0, 0, 0],
        bdgw=[1, 8],
        # For more k-points...
        #nkptgw=2,
        #kptgw=[0, 0, 0,
        #       0.5, 0, 0],
        #bdgw=[1, 8, 1, 8],
        #gw_qprange=-4,
        tmesh=[0, 200, 5],  # (start, step, num)
        zcut="0.2 eV",
    )

    # Set q-path for Fourier interpolation of phonons.
    eph_inp.set_qpath(10)

    # Set q-mesh for phonons DOS.
    eph_inp.set_phdos_qmesh(nqsmall=16, method="tetra")

    # EPH part requires the GS WFK, the DDB file with all perturbations
    # and the database of DFPT potentials (already merged by PhononWork)
    deps = {work0[2]: "WFK", ph_work: ["DDB", "DVDB"]}

    # Now we use the EPH template to perform a convergence study in which
    # we change the q-mesh used to integrate the self-energy and the number of bands.
    # The code will activate the Fourier interpolation of the DFPT potentials if eph_ngqpt_fine != ddb_ngqpt

    for eph_ngqpt_fine in [[4, 4, 4], [8, 8, 8]]:
        # Create empty work to contain EPH tasks with this value of eph_ngqpt_fine
        eph_work = flow.register_work(flowtk.Work())
        #for nband in [50, 100, 200]:
        for nband in [100, 150, 200]:
            new_inp = eph_inp.new_with_vars(eph_ngqpt_fine=eph_ngqpt_fine,
                                            nband=nband)
            eph_work.register_eph_task(new_inp, deps=deps)

    # Generate last work with our best parameters to compute the QP correction in the IBZ
    # We include all occupied states and 4 empty bands.
    # The QP corrections in the IBZ are then interpolate with star functions
    #new_inp = eph_inp.new_with_vars(eph_ngqpt_fine=[8, 8, 8], nband=100)
    #new_inp.pop_vars(["nkptgw", "kptgw", "bdgw"])
    #new_inp["gw_qprange"] = -4
    #flow.register_eph_task(new_inp, deps=deps, task_class=flowtk.EphTask, append=False)

    flow.allocate()

    return flow
Beispiel #26
0
def itest_optic_flow(fwp, tvars):
    """Test optic calculations."""
    if tvars.paral_kgb == 1:
        pytest.xfail("Optic flow with paral_kgb==1 is expected to fail (implementation problem)")
        
    """
    0.002         ! Value of the smearing factor, in Hartree
    0.0003  0.3   ! Difference between frequency values (in Hartree), and maximum frequency ( 1 Ha is about 27.211 eV)
    0.000         ! Scissor shift if needed, in Hartree
    0.002         ! Tolerance on closeness of singularities (in Hartree)
    1             ! Number of components of linear optic tensor to be computed
    11            ! Linear coefficients to be computed (x=1, y=2, z=3)
    2             ! Number of components of nonlinear optic tensor to be computed
    123 222       ! Non-linear coefficients to be computed
    """
    optic_input = abilab.OpticInput(
        broadening=0.002,
        domega=0.0003,
        maxomega=0.3,
        scissor=0.000,
        tolerance=0.002,
        num_lin_comp=1,
        lin_comp=11,
        num_nonlin_comp=2,
        nonlin_comp=(123, 222),
    )
    print(optic_input)
    #raise ValueError()

    scf_inp, nscf_inp, ddk1, ddk2, ddk3 = make_inputs(tvars)

    flow = flowtk.Flow(fwp.workdir, manager=fwp.manager)

    bands_work = flowtk.BandStructureWork(scf_inp, nscf_inp)
    flow.register_work(bands_work)

    # work with DDK tasks.
    ddk_work = flowtk.Work()
    for inp in [ddk1, ddk2, ddk3]:
        ddk_work.register_ddk_task(inp, deps={bands_work.nscf_task: "WFK"})

    flow.register_work(ddk_work)
    flow.allocate()
    flow.build_and_pickle_dump(abivalidate=True)

    # Run the tasks
    for task in flow.iflat_tasks():
        task.start_and_wait()
        assert task.status == task.S_DONE

    flow.check_status()
    assert flow.all_ok

    # Optic does not support MPI with ncores > 1 hence we have to construct a manager with mpi_procs==1
    shell_manager = fwp.manager.to_shell_manager(mpi_procs=1)

    # Build optic task and register it
    optic_task1 = flowtk.OpticTask(optic_input, nscf_node=bands_work.nscf_task, ddk_nodes=ddk_work,
                                   manager=shell_manager)

    flow.register_task(optic_task1)
    flow.allocate()
    flow.build_and_pickle_dump(abivalidate=True)

    optic_task1.start_and_wait()
    assert optic_task1.status == optic_task1.S_DONE

    # Now we do a similar calculation but the dependencies are represented by
    # strings with the path to the input files instead of task objects.
    ddk_nodes = [task.outdir.has_abiext("1WF") for task in ddk_work]
    #ddk_nodes = [task.outdir.has_abiext("DDK") for task in ddk_work]
    print("ddk_nodes:", ddk_nodes)
    assert all(ddk_nodes)

    #nscf_node = bands_work.nscf_task
    nscf_node = bands_work.nscf_task.outdir.has_abiext("WFK")
    assert nscf_node

    # This does not work yet
    optic_task2 = flowtk.OpticTask(optic_input, nscf_node=nscf_node, ddk_nodes=ddk_nodes)
    flow.register_task(optic_task2)
    flow.allocate()
    flow.build_and_pickle_dump(abivalidate=True)
    assert len(flow) == 4

    optic_task2.start_and_wait()
    assert optic_task2.status == optic_task2.S_DONE

    flow.check_status()
    flow.show_status()
    assert flow.all_ok
    assert all(work.finalized for work in flow)

    #assert flow.validate_json_schema()

    # Test get_results
    optic_task2.get_results()
Beispiel #27
0
def build_flow(options, paral_kgb=0):
    """
    Build flow for the calculation of optical properties with optic + band structure
    along high-symmetry k-path. DDK are computed with 3 k-meshes of increasing density
    to monitor the convergece of the spectra.
    """
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    if not options.workdir:
        options.workdir = os.path.basename(sys.argv[0]).replace(
            ".py", "").replace("run_", "flow_")

    multi = abilab.MultiDataset(structure=abidata.structure_from_ucell("GaAs"),
                                pseudos=abidata.pseudos(
                                    "31ga.pspnc", "33as.pspnc"),
                                ndtset=2)

    # Usa same shifts in all tasks.
    shiftk = [[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0],
              [0.0, 0.0, 0.5]]

    # Global variables.
    multi.set_vars(ecut=2, paral_kgb=paral_kgb)

    # Dataset 1 (GS run)
    multi[0].set_vars(tolvrs=1e-8, nband=4)
    multi[0].set_kmesh(ngkpt=[4, 4, 4], shiftk=shiftk)

    # NSCF run on k-path with large number of bands
    multi[1].set_vars(iscf=-2, nband=20, tolwfr=1.e-9)
    multi[1].set_kpath(ndivsm=10)

    # Initialize the flow.
    flow = flowtk.Flow(options.workdir, manager=options.manager)

    # GS to get the density + NSCF along the path.
    scf_inp, nscf_inp = multi.split_datasets()
    bands_work = flowtk.BandStructureWork(scf_inp, nscf_inp)
    flow.register_work(bands_work)

    # Build OpticInput used to compute optical properties.
    optic_input = abilab.OpticInput(
        broadening=0.002,  # Value of the smearing factor, in Hartree
        domega=0.0003,  # Frequency mesh.
        maxomega=0.3,
        scissor=0.000,  # Scissor shift if needed, in Hartree
        tolerance=0.002,  # Tolerance on closeness of singularities (in Hartree)
        num_lin_comp=
        2,  # Number of components of linear optic tensor to be computed
        lin_comp=(11,
                  33),  # Linear coefficients to be computed (x=1, y=2, z=3)
        num_nonlin_comp=
        2,  # Number of components of nonlinear optic tensor to be computed
        nonlin_comp=(123, 222),  # Non-linear coefficients to be computed
    )

    # ddk_nband is fixed here, in principle it depends on nelect and the frequency range in chi(w).
    ddk_nband = 20

    # Perform converge study wrt ngkpt (shiftk is constant).
    ngkpt_convergence = [[4, 4, 4], [8, 8, 8], [16, 16, 16]]

    from abipy.flowtk.dfpt_works import NscfDdksWork
    for ddk_ngkpt in ngkpt_convergence:
        # Build work for NSCF from DEN produced by the first GS task + 3 DDKs.
        # All tasks use more bands and a denser k-mesh defined by ddk_ngkpt.
        ddks_work = NscfDdksWork.from_scf_task(bands_work[0], ddk_ngkpt,
                                               shiftk, ddk_nband)
        flow.register_work(ddks_work)

        # Build optic task to compute chi with this value of ddk_ngkpt.
        optic_task = flowtk.OpticTask(
            optic_input,
            nscf_node=ddks_work.task_with_ks_energies,
            ddk_nodes=ddks_work.ddk_tasks,
            use_ddknc=False)
        ddks_work.register_task(optic_task)

    return flow
Beispiel #28
0
def build_flow(options, paral_kgb=0):
    # Working directory (default is the name of the script with '.py' removed and "run_" replaced by "flow_")
    workdir = options.workdir
    if not options.workdir:
        workdir = os.path.basename(__file__).replace(".py", "").replace(
            "run_", "flow_")

    multi = abilab.MultiDataset(structure=data.structure_from_ucell("GaAs"),
                                pseudos=data.pseudos("31ga.pspnc",
                                                     "33as.pspnc"),
                                ndtset=5)

    # Global variables
    kmesh = dict(ngkpt=[4, 4, 4],
                 nshiftk=4,
                 shiftk=[[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0],
                         [0.0, 0.0, 0.5]])

    global_vars = dict(ecut=2, paral_kgb=paral_kgb)
    global_vars.update(kmesh)

    multi.set_vars(global_vars)

    # Dataset 1 (GS run)
    multi[0].set_vars(
        tolvrs=1e-6,
        nband=4,
    )

    # NSCF run with large number of bands, and points in the the full BZ
    multi[1].set_vars(
        iscf=-2,
        nband=20,
        nstep=25,
        kptopt=1,
        tolwfr=1.e-9,
        #kptopt=3,
    )

    # Fourth dataset : ddk response function along axis 1
    # Fifth dataset : ddk response function along axis 2
    # Sixth dataset : ddk response function along axis 3
    for dir in range(3):
        rfdir = 3 * [0]
        rfdir[dir] = 1

        multi[2 + dir].set_vars(
            iscf=-3,
            nband=20,
            nstep=1,
            nline=0,
            prtwf=3,
            kptopt=3,
            nqpt=1,
            qpt=[0.0, 0.0, 0.0],
            rfdir=rfdir,
            rfelfd=2,
            tolwfr=1.e-9,
        )

    scf_inp, nscf_inp, ddk1, ddk2, ddk3 = multi.split_datasets()

    # Initialize the flow.
    flow = flowtk.Flow(workdir, manager=options.manager, remove=options.remove)

    bands_work = flowtk.BandStructureWork(scf_inp, nscf_inp)
    flow.register_work(bands_work)

    ddk_work = flowtk.Work()
    for inp in [ddk1, ddk2, ddk3]:
        ddk_work.register_ddk_task(inp, deps={bands_work.nscf_task: "WFK"})

    flow.register_work(ddk_work)

    # Optic does not support MPI with ncpus > 1.
    optic_input = abilab.OpticInput(
        broadening=0.002,  # Value of the smearing factor, in Hartree
        domega=0.0003,  # Frequency mesh.
        maxomega=0.3,
        scissor=0.000,  # Scissor shift if needed, in Hartree
        tolerance=0.002,  # Tolerance on closeness of singularities (in Hartree)
        num_lin_comp=
        1,  # Number of components of linear optic tensor to be computed
        lin_comp=11,  # Linear coefficients to be computed (x=1, y=2, z=3)
        num_nonlin_comp=
        2,  # Number of components of nonlinear optic tensor to be computed
        nonlin_comp=(123, 222),  # Non-linear coefficients to be computed
    )

    # TODO
    # Check is the order of the 1WF files is relevant. Can we use DDK files ordered
    # in an arbitrary way or do we have to pass (x,y,z)?
    optic_task = flowtk.OpticTask(optic_input,
                                  nscf_node=bands_work.nscf_task,
                                  ddk_nodes=ddk_work)
    flow.register_task(optic_task)

    return flow