def itest_phonon_restart(fwp): """Test the restart of phonon calculations with the scheduler.""" # Crystalline AlAs: computation of the second derivative of the total energy structure = abidata.structure_from_ucell("AlAs") # List of q-points for the phonon calculation (4,4,4) mesh. qpoints = np.reshape([ 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 2.50000000E-01, 0.00000000E+00, 0.00000000E+00, #5.00000000E-01, 0.00000000E+00, 0.00000000E+00, # XXX Uncomment this line to test restart from 1DEN # Too long --> disabled ], (-1, 3)) # Global variables used both for the GS and the DFPT run. global_vars = dict(nband=4, ecut=3.0, ngkpt=[4, 4, 4], shiftk=[0, 0, 0], tolvrs=1.0e-5, ) multi = abilab.MultiDataset(structure=structure, pseudos=abidata.pseudos("13al.981214.fhi", "33as.pspnc"), ndtset=1+len(qpoints)) multi.set_vars(global_vars) for i, qpt in enumerate(qpoints): # Response-function calculation for phonons. multi[i+1].set_vars( rfphon=1, # Will consider phonon-type perturbation. nqpt=1, # One wavevector is to be considered. qpt=qpt, # q-wavevector. kptopt=3, nstep=5, # This is to trigger the phonon restart. ) #rfatpol 1 1 # Only the first atom is displaced #rfdir 1 0 0 # Along the first reduced coordinate axis #kptopt 2 # Automatic generation of k points, taking # i == 0 --> restart from WFK if i == 1: multi[i+1].set_vars(prtwf=-1, nstep=5) # Restart with WFK and smart- io. if i == 2: multi[i+1].set_vars(prtwf=0, nstep=8) # Restart from 1DEN. Too long --> disabled. all_inps = multi.split_datasets() scf_input, ph_inputs = all_inps[0], all_inps[1:] flow = abilab.phonon_flow(fwp.workdir, scf_input, ph_inputs, manager=fwp.manager) flow.set_garbage_collector() for task in flow.iflat_tasks(): task.manager.qadapter.max_num_launches = 20 assert flow.make_scheduler().start() == 0 flow.check_status(show=True, verbose=1) assert all(work.finalized for work in flow) assert flow.all_ok assert sum(task.num_restarts for task in flow.iflat_tasks()) > 0
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
def make_inputs(paw=False): pseudos = abidata.pseudos("14si.pspnc", "8o.pspnc") if not paw else \ abidata.pseudos("Si.GGA_PBE-JTH-paw.xml", "o.paw") structure = abidata.structure_from_ucell("SiO2-alpha") multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=4) ecut = 24 multi.set_vars( ecut=ecut, pawecutdg=ecut * 2 if paw else None, paral_kgb=0, istwfk="*1", timopt=-1, ) multi.set_kmesh(ngkpt=[4, 4, 3], shiftk=[0.0, 0.0, 0.0]) gs, nscf, scr, sigma = multi.split_datasets() # Dataset 1 (GS run) gs.set_vars( tolvrs=1e-6, nband=28, ) # Dataset 2 (NSCF run) nscf.set_vars( iscf=-2, tolwfr=1e-4, nband=600, nbdbuf=200, ) # Dataset3: Calculation of the screening. scr.set_vars( optdriver=3, gwpara=2, nband=25, ecutwfn=ecut, symchi=1, inclvkb=0, ecuteps=6.0, ) # Dataset4: Calculation of the Self-Energy matrix elements (GW corrections) sigma.set_vars( optdriver=4, gwpara=2, ecutwfn=ecut, ecuteps=6.0, ecutsigx=ecut, symsigma=1, gw_qprange=1, ) return gs, nscf, scr, sigma
def make_inputs(paw=False): # Crystalline silicon # Calculation of the GW correction to the direct band gap in Gamma # Dataset 1: ground state calculation # Dataset 2: BSE with haydock method and model dielectric function. structure = abilab.Structure.from_file(abidata.cif_file("si.cif")) pseudos = abidata.pseudos("14si.pspnc") if not paw else abidata.pseudos( "Si.GGA_PBE-JTH-paw.xml") multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2) ecut = 8 multi.set_vars( ecut=ecut, pawecutdg=ecut * 4 if paw else None, nsppol=1, timopt=-1, istwfk="*1", paral_kgb=0, ) # This grid is the most economical, but does not contain the Gamma point. multi.set_kmesh( ngkpt=[8, 8, 8], shiftk=[0.0, 0.0, 0.0], ) gs, bse = multi.split_datasets() gs.set_vars( tolvrs=1e-6, nband=8, ) # Dataset 6 BSE equation with Model dielectric function and Haydock (only resonant + W + v) # Note that SCR file is not needed here bse.set_vars( optdriver=99, ecutwfn=ecut, ecuteps=4.0, inclvkb=2, bs_algorithm=2, # Haydock bs_haydock_niter=60, # No. of iterations for Haydock bs_exchange_term=1, bs_coulomb_term=21, # Use model W and full W_GG. mdf_epsinf=12.0, bs_calctype=1, # Use KS energies and orbitals to construct L0 mbpt_sciss="0.8 eV", bs_coupling=0, bs_loband=2, nband=8, bs_freq_mesh="0 10 0.1 eV", bs_hayd_term=0, # No terminator #gwmem=01 # Compute the model-dielectric function on-the-fly. ) return gs, bse
def make_scf_nscf_dos_inputs(structure, pseudos, luj_params, paral_kgb=1): # Input file taken from tldau_2.in multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=3) # Global variables global_vars = dict( # ecut=12, pawecutdg=30, nband=40, occopt=7, tsmear=0.015, nstep=50, paral_kgb=paral_kgb, # # Spin nsppol=1, nspden=2, nspinor=1, spinat=[0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0], # Kpoint Grid # The k point grid is not symmetric, but the calculations being # for the ground-state, this is not a problem. ) multi.set_vars(global_vars) multi.set_vars(luj_params.to_abivars()) # GS run. multi[0].set_vars( iscf=17, toldfe=1.0e-8, ngkpt=[2, 2, 2], chksymbreak=0, ) # Band structure run. multi[1].set_kpath(ndivsm=6) multi[1].set_vars(tolwfr=1e-10) # Dos calculation. multi[2].set_vars( iscf=-3, # NSCF calculation ngkpt=structure.calc_ngkpt(nksmall=8), shiftk=[0.0, 0.0, 0.0], nshiftk=1, tolwfr=1.e-8, #pawprtdos=1, ) # Generate two input files for the GS and the NSCF run scf_input, nscf_input, dos_input = multi.split_datasets() return scf_input, nscf_input, dos_input
def make_inputs(tvars): """Constrcut the input files.""" structure = abidata.structure_from_ucell("GaAs") multi = abilab.MultiDataset(structure, pseudos=abidata.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=tvars.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-8) #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 idir in range(3): rfdir = 3 * [0] rfdir[idir] = 1 multi[2+idir].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 return multi.split_datasets()
def make_inputs(paral_kgb=1): """ Returns a tuple of 4 input files for SCF, NSCF, SCR, SIGMA calculations. These files are then used as templates for the convergence study wrt ecuteps and the number of bands in W. """ multi = abilab.MultiDataset(abidata.structure_from_ucell("SiC"), pseudos=abidata.pseudos( "14si.pspnc", "6c.pspnc"), ndtset=4) ecut = 12 global_vars = dict(ecut=ecut, istwfk="*1", paral_kgb=paral_kgb, gwpara=2) ecuteps = 4 ngkpt = [4, 4, 4] shiftk = [0, 0, 0] multi.set_vars(global_vars) multi.set_kmesh(ngkpt=ngkpt, shiftk=shiftk) # SCF multi[0].set_vars( nband=10, tolvrs=1.e-8, ) # NSCF multi[1].set_vars(nband=25, tolwfr=1.e-8, iscf=-2) # SCR multi[2].set_vars( optdriver=3, ecutwfn=ecut, nband=20, symchi=1, inclvkb=0, ecuteps=ecuteps, ) # SIGMA multi[3].set_vars( optdriver=4, nband=20, ecutwfn=ecut, ecutsigx=ecut, #ecutsigx=(4*ecut), ! This is problematic symsigma=1, ecuteps=ecuteps, ) multi[3].set_kptgw(kptgw=[[0, 0, 0], [0.5, 0, 0]], bdgw=[1, 8]) return multi.split_datasets()
def make_ion_ioncell_inputs(paral_kgb=0): structure = abilab.Structure.from_file(abidata.cif_file("si.cif")) # Perturb the structure (random perturbation of 0.1 Angstrom) # then compress the volume to trigger dilatmx. structure.perturb(distance=0.1) structure.scale_lattice(structure.volume * 0.6) global_vars = dict( ecut=4, ngkpt=[4, 4, 4], shiftk=[0, 0, 0], nshiftk=1, chksymbreak=0, paral_kgb=paral_kgb, iomode=3, #prtwf=0, ) multi = abilab.MultiDataset(structure, pseudos=abidata.pseudos("14si.pspnc"), ndtset=2) # Global variables multi.set_vars(global_vars) # Dataset 1 (Atom Relaxation) multi[0].set_vars( optcell=0, ionmov=2, tolrff=0.02, tolmxf=5.0e-5, #ntime=50, ntime=3, #To test the restart #dilatmx=1.1, # FIXME: abinit crashes if I don't use this ) # Dataset 2 (Atom + Cell Relaxation) multi[1].set_vars( optcell=1, ionmov=2, ecutsm=0.5, dilatmx=1.02, tolrff=0.02, tolmxf=5.0e-5, strfact=100, #ntime=50, ntime=3, # To test the restart ) ion_inp, ioncell_inp = multi.split_datasets() return ion_inp, ioncell_inp
def raman_workflow(structure, pseudos, scf_t, ksamp): # Generate 3 different input files for computing optical properties with BSE. inp = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2) inp.set_vars(**global_vars) vars_ksamp = ksamp.to_abivars() vars_ksamp.pop("#comment", None) inp.set_vars(**vars_ksamp) # NSCF run inp[0].set_vars( iscf=-2, nband=10 * len(structure), nbdbuf=2 * len(structure), nstep=500, tolwfr=1.e-22, ) inp[1].set_vars( gwmem=10, gwpara=2, optdriver=99, nband=5 * len(structure), # 10 bands for 2 atoms bs_loband=1 * len(structure), # start at 2 for 2 atoms bs_algorithm=2, # Haydock bs_calctype=1, # KS wavefunctions bs_coulomb_term=21, # Use model dielectric function mdf_epsinf=12.0, bs_exchange_term=1, # Exchange term included bs_freq_mesh="0 10 0.01 eV", bs_hayd_term=0, bs_coupling=0, bs_haydock_tol="-0.01 0", bs_haydock_niter=1000, inclvkb=2, ecuteps=4, soenergy="0.8 eV", ecutwfn=global_vars["ecut"], ) nscf_inp, bse_inp = inp.split_datasets() workflow = abilab.Work() nscf_t = workflow.register(nscf_inp, deps={scf_t: "DEN"}, task_class=abilab.NscfTask) bse_t = workflow.register_bse_task(bse_inp, deps={nscf_t: "WFK"}) return workflow
def scf_ph_inputs(tvars=None): """ This function constructs the input files for the phonon calculation: GS input + the input files for the phonon calculation. """ # Crystalline AlAs: computation of the second derivative of the total energy structure = abidata.structure_from_ucell("AlAs") # List of q-points for the phonon calculation (4,4,4) mesh. qpoints = [ 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 2.50000000E-01, 0.00000000E+00, 0.00000000E+00, 5.00000000E-01, 0.00000000E+00, 0.00000000E+00, 2.50000000E-01, 2.50000000E-01, 0.00000000E+00, 5.00000000E-01, 2.50000000E-01, 0.00000000E+00, -2.50000000E-01, 2.50000000E-01, 0.00000000E+00, 5.00000000E-01, 5.00000000E-01, 0.00000000E+00, -2.50000000E-01, 5.00000000E-01, 2.50000000E-01, ] qpoints = np.reshape(qpoints, (-1,3)) # Global variables used both for the GS and the DFPT run. global_vars = dict(nband=4, ecut=3.0, ngkpt=[4, 4, 4], shiftk=[0, 0, 0], tolvrs=1.0e-6, paral_kgb=0 if tvars is None else tvars.paral_kgb, ) multi = abilab.MultiDataset(structure=structure, pseudos=abidata.pseudos("13al.981214.fhi", "33as.pspnc"), ndtset=1+len(qpoints)) multi.set_vars(global_vars) for i, qpt in enumerate(qpoints): # Response-function calculation for phonons. multi[i+1].set_vars( nstep=20, rfphon=1, # Will consider phonon-type perturbation nqpt=1, # One wavevector is to be considered qpt=qpt, # This wavevector is q=0 (Gamma) kptopt=3, ) #rfatpol 1 1 # Only the first atom is displaced #rfdir 1 0 0 # Along the first reduced coordinate axis #kptopt 2 # Automatic generation of k points, taking # Split input into gs_inp and ph_inputs return multi.split_datasets()
def itest_metagga_ebands_flow(fwp, tvars): """ Test band structure calculation with meta-GGA """ if not fwp.abinit_build.has_libxc: pytest.skip( "itest_metagga_ebands_flow requires libxc support in Abinit.") from abipy.data.hgh_pseudos import HGH_TABLE multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=HGH_TABLE, ndtset=2) # Global variables shiftk = [ float(s) for s in "0.5 0.5 0.5 0.5 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5".split() ] multi.set_vars(ecut=20, diemac=12, iomode=3, ixc=-208012, prtkden=1, usekden=1) # Dataset 1 multi[0].set_vars(tolvrs=1e-7) multi[0].set_kmesh(ngkpt=[2, 2, 2], shiftk=shiftk) # Dataset 2 multi[1].set_vars(tolwfr=1e-8) multi[1].set_kpath(ndivsm=2) scf_input, nscf_input = multi.split_datasets() work = flowtk.works.BandStructureWork(scf_input=scf_input, nscf_input=nscf_input) flow = abilab.Flow(workdir=fwp.workdir, manager=fwp.manager) flow.register_work(work) 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)
def make_ngkpt_flow(): ngkpt_list = [(2, 2, 2), (4, 4, 4), (6, 6, 6), (8, 8, 8)] multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list)) # Global variables multi.set_vars(ecut=10, tolvrs=1e-9) for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0]) return NgkptFlow.from_inputs(workdir="flow_base3_ngkpt", inputs=multi.split_datasets())
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_") flow = flowtk.Flow(workdir, manager=options.manager, remove=options.remove) pseudos = data.pseudos("14si.pspnc", "6c.pspnc") structure = data.structure_from_ucell("SiC") global_vars = dict( chksymbreak=0, ecut=20, paral_kgb=0, iomode=3, ) 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]] multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2) multi.set_vars(global_vars) relax_inp, nscf_inp = multi.split_datasets() relax_inp.set_kmesh(ngkpt=ngkpt, shiftk=shiftk) relax_inp.set_vars( toldff=1e-6, tolmxf=1e-5, strfact=100, ecutsm=0.5, dilatmx=1.15, ntime=100, ionmov=2, optcell=1, ) nscf_inp.set_kpath(ndivsm=20) nscf_inp.tolwfr = 1e-22 # Initialize the work. relax_task = flow.register_task(relax_inp, task_class=flowtk.RelaxTask) #work = RelaxWork(self, ion_input, ioncell_input, workdir=None, manager=None): #nscf_task = flow.register_task(nscf_inp, deps={relax_task: "DEN"}, task_class=flowtk.NscfTask) return flow
def build_flow(options): """ Build and return a flow performing structural relaxations with different k-point samplings. """ # Set 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_vs_kpts.py") options.workdir = os.path.basename(__file__).replace( ".py", "").replace("run_", "flow_") # List of k-meshes. ngkpt_list = [ [3, 3, 2], [6, 6, 4], [8, 8, 6], ] structure = abilab.Structure.from_file(abidata.cif_file("gan2.cif")) pseudos = abidata.pseudos("Ga.oncvpsp", "N.oncvpsp") # Build multidataset. multi = abilab.MultiDataset(structure=structure, pseudos=pseudos, ndtset=len(ngkpt_list)) # Set global variables for structural relaxation. Note dilatmx and ecutsm # Ecut should depend on pseudos. multi.set_vars( ecut=15, # Too low optcell=2, ionmov=3, tolrff=5.0e-2, tolmxf=5.0e-5, ntime=50, dilatmx=1.05, # Important! ecutsm=0.5, # Important! ) # Here we set the k-meshes (Gamma-centered for simplicity) for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0]) # As the calculations are independent, we can use Flow.from_inputs # and call split_datasets to create len(ngkpt_list) inputs. # Note that it's a good idea to specify the task_class so that AbiPy knows how to restart the calculation. return flowtk.Flow.from_inputs(options.workdir, inputs=multi.split_datasets(), task_class=flowtk.RelaxTask)
def make_ngkpt_flow(ngkpt_list=((2, 2, 2), (4, 4, 4), (6, 6, 6), (8, 8, 8)), structure_file=None, metal=False): """ A `factory function` (a function that returns an instance of the class defined above. If no specific system is specified, structure_file=None, an flow for silicon in constructed and returned. """ # Defining the structure and adding the appropriate pseudo potentials if structure_file is None: multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list)) workdir = "flow_lesson_Si_kpoint_convergence" else: structure = abilab.Structure.from_file(structure_file) pseudos = get_pseudos(structure) multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=len(ngkpt_list)) workdir = "flow_lesson_" + structure.composition.reduced_formula + "_kpoint_convergence" # Add mnemonics to input file. multi.set_mnemonics(True) # Global variables multi.set_vars(ecut=10, tolvrs=1e-9) if metal: multi.set_vars(occopt=7, tsmear=0.04) # Specific variables for the different calculations for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0]) return abilab.Flow.from_inputs(workdir=workdir, inputs=multi.split_datasets())
def make_ecut_flow(structure_file=None, ecut_list=(10, 12, 14, 16, 18)): """ Build and return a `Flow` to perform a convergence study wrt to ecut. Args: structure_file: (optional) file containing the crystalline structure. If None, crystalline silicon structure. ecut_list: List of cutoff energies to be investigated. """ # Define the structure and add the necessary pseudos: if structure_file is None: multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ecut_list)) workdir = "flow_Si_ecut_convergence" else: structure = abilab.Structure.from_file(structure_file) pseudos = abilab.PseudoTable() ## todo fix this multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=len(ecut_list)) workdir = "flow_" + structure.composition.reduced_formula + "_ecut_convergence" # Add mnemonics to the input files. multi.set_mnemonics(True) # Global variables multi.set_vars(tolvrs=1e-9) multi.set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0]) # Here we set the value of ecut used by the i-th task. for i, ecut in enumerate(ecut_list): multi[i].set_vars(ecut=ecut) return abilab.Flow.from_inputs(workdir=workdir, inputs=multi.split_datasets())
def make_ion_ioncell_inputs(tvars, dilatmx, scalevol=1, ntime=50): structure = abilab.Structure.from_file(abidata.cif_file("si.cif")) # Perturb the structure (random perturbation of 0.1 Angstrom) #structure.perturb(distance=0.01) # Compress the lattice so that ABINIT complains about dilatmx structure.scale_lattice(structure.volume * scalevol) global_vars = dict( ecut=6, ecutsm=0.5, ngkpt=[4, 4, 4], shiftk=[0, 0, 0], nshiftk=1, chksymbreak=0, paral_kgb=tvars.paral_kgb, ) multi = abilab.MultiDataset(structure, pseudos=abidata.pseudos("14si.pspnc"), ndtset=2) # Global variables multi.set_vars(global_vars) # Dataset 1 (Atom Relaxation) multi[0].set_vars( optcell=0, ionmov=2, tolrff=0.02, tolmxf=5.0e-5, ntime=ntime, ) # Dataset 2 (Atom + Cell Relaxation) multi[1].set_vars( optcell=1, ionmov=2, dilatmx=dilatmx, tolrff=0.02, tolmxf=5.0e-5, strfact=100, ntime=ntime, ) ion_inp, ioncell_inp = multi.split_datasets() return ion_inp, ioncell_inp
def make_scf_nscf_inputs(tvars, pp_paths, nstep=50): """ Returns two input files: GS run and NSCF on a high symmetry k-mesh """ multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos(pp_paths), ndtset=2) nval = multi[0].num_valence_electrons assert all(inp.num_valence_electrons == 8 for inp in multi) # Global variables ecut = 4 global_vars = dict( ecut=ecut, nband=int(nval / 2), nstep=nstep, paral_kgb=tvars.paral_kgb, timopt=-1, ) if multi.ispaw: global_vars.update(pawecutdg=2 * ecut) multi.set_vars(global_vars) # Dataset 1 (GS run) multi[0].set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0]) #multi[0].set_vars(prtden=1, prtpot=1, prtvha=1, prtvxc=1, prtvhxc=1) multi[0].set_vars(tolvrs=1e-4) # Dataset 2 (NSCF run) 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 ] multi[1].set_kpath(ndivsm=2, kptbounds=kptbounds) multi[1].set_vars(tolwfr=1e-6) # Generate two input files for the GS and the NSCF run. scf_input, nscf_input = multi.split_datasets() return scf_input, nscf_input
def make_scf_nscf_inputs(paral_kgb=1): """Returns two input files: GS run and NSCF on a high symmetry k-mesh.""" pseudos = abidata.pseudos("14si.pspnc") #pseudos = data.pseudos("Si.GGA_PBE-JTH-paw.xml") multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=pseudos, ndtset=2) multi.set_mnemonics(True) # Global variables ecut = 6 global_vars = dict( ecut=ecut, nband=8, timopt=-1, istwfk="*1", nstep=15, paral_kgb=paral_kgb, iomode=3, ) if multi.ispaw: global_vars.update(pawecutdg=2 * ecut) multi.set_vars(global_vars) # Dataset 1 (GS run) multi[0].set_kmesh(ngkpt=[8, 8, 8], shiftk=[0, 0, 0]) multi[0].set_vars(tolvrs=1e-6) # Dataset 2 (NSCF run) 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 ] multi[1].set_kpath(ndivsm=6, kptbounds=kptbounds) multi[1].set_vars(tolwfr=1e-12) # Generate two input files for the GS and the NSCF run scf_input, nscf_input = multi.split_datasets() return scf_input, nscf_input
def make_ebands_flow(): """Band structure calculation.""" multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=2) # Global variables multi.set_vars(ecut=10) # Dataset 1 multi[0].set_vars(tolvrs=1e-9) multi[0].set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0]) # Dataset 2 multi[1].set_vars(tolwfr=1e-15) multi[1].set_kpath(ndivsm=5) scf_input, nscf_input = multi.split_datasets() return flowtk.bandstructure_flow(workdir="flow_base3_ebands", scf_input=scf_input, nscf_input=nscf_input)
def build_relax_flow(options): """ Crystalline silicon: computation of the optimal lattice parameter. Convergence with respect to the number of k points. Similar to tbase3_4.in """ # Structural relaxation for different k-point samplings. ngkpt_list = [(2, 2, 2), (4, 4, 4)] shiftk = [ float(s) for s in "0.5 0.5 0.5 0.5 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5".split() ] multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list)) # Global variables multi.set_vars( ecut=8, tolvrs=1e-9, optcell=1, ionmov=3, ntime=10, dilatmx=1.05, ecutsm=0.5, diemac=12, iomode=3, ) for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=shiftk) workdir = options.workdir if (options and options.workdir) else "flow_base3_relax" return flowtk.Flow.from_inputs(workdir, inputs=multi.split_datasets(), task_class=flowtk.RelaxTask)
def build_ngkpt_flow(options): """ Crystalline silicon: computation of the total energy Convergence with respect to the number of k points. Similar to tbase3_3.in Args: options: Command line options. Return: Abinit Flow object. """ # Definition of the different grids ngkpt_list = [(2, 2, 2), (4, 4, 4), (6, 6, 6), (8, 8, 8)] # These shifts will be the same for all grids shiftk = [ float(s) for s in "0.5 0.5 0.5 0.5 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5".split() ] # Build MultiDataset object (container of `ndtset` inputs). # Structure is initialized from CIF file. multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list)) # These variables are the same in each input. multi.set_vars(ecut=8, toldfe=1e-6, diemac=12.0, iomode=3) # Each input has its own value of `ngkpt`. shiftk is constant. for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=shiftk) workdir = options.workdir if (options and options.workdir) else "flow_base3_ngkpt" # Split the inputs by calling multi.datasets() and pass the list of inputs to Flow.from_inputs. return flowtk.Flow.from_inputs(workdir, inputs=multi.split_datasets())
def make_relax_flow(structure_file=None): """ Build and return a flow that perform a structural relaxation for different k-point samplings. """ ngkpt_list = [[3, 3, 2], [6, 6, 4], [8, 8, 6]] if structure_file is None: structure = abilab.Structure.from_file(abidata.cif_file("gan2.cif")) else: structure = abilab.Structure.from_file(structure_file) multi = abilab.MultiDataset(structure=structure, pseudos=get_pseudos(structure), ndtset=len(ngkpt_list)) # Add mnemonics to input file. multi.set_mnemonics(True) # Global variables multi.set_vars( ecut=20, tolrff=5.0e-2, nstep=30, optcell=2, ionmov=3, ntime=50, dilatmx=1.05, ecutsm=0.5, tolmxf=5.0e-5, ) for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0]) return abilab.Flow.from_inputs("flow_gan_relax", inputs=multi.split_datasets(), task_class=abilab.RelaxTask)
def make_scf_nscf_inputs(structure, pseudos, paral_kgb=1): """return GS, NSCF (band structure), and DOSes input.""" multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=5) # Global variables global_vars = dict( ecut=10, nband=11, timopt=-1, occopt=4, # Marzari smearing tsmear=0.03, paral_kgb=paral_kgb, ) multi.set_vars(global_vars) # Dataset 1 (GS run) multi[0].set_kmesh(ngkpt=[8, 8, 8], shiftk=structure.calc_shiftk()) multi[0].set_vars(tolvrs=1e-6) # Dataset 2 (NSCF Band Structure) multi[1].set_kpath(ndivsm=6) multi[1].set_vars(tolwfr=1e-12) # Dos calculations with increasing k-point sampling. for i, nksmall in enumerate([4, 8, 16]): multi[i + 2].set_vars( iscf=-3, # NSCF calculation ngkpt=structure.calc_ngkpt(nksmall), shiftk=[0.0, 0.0, 0.0], tolwfr=1.0e-10, ) # return GS, NSCF (band structure), DOSes input. return multi.split_datasets()
def make_relax_flow(): # Structural relaxation for different k-point samplings. ngkpt_list = [(2, 2, 2), (4, 4, 4)] multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list)) # Global variables multi.set_vars( ecut=10, tolvrs=1e-9, optcell=1, ionmov=3, ntime=10, dilatmx=1.05, ecutsm=0.5, ) for i, ngkpt in enumerate(ngkpt_list): multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0]) return RelaxFlow.from_inputs("flow_base3_relax", inputs=multi.split_datasets(), task_class=flowtk.RelaxTask)
def make_inputs(options): structure = abilab.Structure.from_abivars(unit_cell) if options.paw: raise RuntimeError("PAW is not implemented") else: pseudos = abidata.pseudos("26fe.pspnc", "83-Bi.GGA.fhi", '8o.pspnc') #pseudos = ["fe.pot", "bi.pot", 'o.pot'] gs_inp = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=2) gs_inp.set_vars(global_vars) gs_inp.set_vars(timopt=-1, kptopt=3, mem_test=0) gs_inp[0].set_vars(tolvrs=1.0e-18) gs_inp[1].set_vars( iscf=-2, tolwfr=1.0e-22, nband=100, nbdbuf=10, ) return gs_inp.split_datasets()
def make_scf_nscf_inputs(structure, paral_kgb=1): multi = abilab.MultiDataset(structure, pseudos=data.pseudos("14si.pspnc"), ndtset=2) # Global variables global_vars = dict( ecut=6, nband=8, timopt=-1, paral_kgb=0, #nstep=4, # This is not enough to converge. Used to test the automatic restart. nstep=10, iomode=3, ) multi.set_vars(global_vars) # Dataset 1 (GS run) multi[0].set_kmesh(ngkpt=[8, 8, 8], shiftk=[0, 0, 0]) multi[0].set_vars(tolvrs=1e-6) # Dataset 2 (NSCF run) 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 ] multi[1].set_kpath(ndivsm=6, kptbounds=kptbounds) multi[1].set_vars(tolwfr=1e-12) # Generate two input files for the GS and the NSCF run scf_input, nscf_input = multi.split_datasets() return scf_input, nscf_input
def make_g0w0_inputs(ngkpt, tvars): """ Input files for the calculation of the GW corrections. Returns: gs_input, nscf_input, scr_input, sigma_input """ multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"), pseudos=abidata.pseudos("14si.pspnc"), ndtset=4) # This grid is the most economical, but does not contain the Gamma point. scf_kmesh = dict( ngkpt=ngkpt, 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] ) # This grid contains the Gamma point, which is the point at which # we will compute the (direct) band gap. gw_kmesh = dict( ngkpt=ngkpt, shiftk=[0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.5, 0.5, 0.5, 0.0] ) # Global variables. gw_kmesh is used in all datasets except DATASET 1. ecut = 4 multi.set_vars( ecut=ecut, pawecutdg=ecut*2 if multi.ispaw else None, istwfk="*1", paral_kgb=tvars.paral_kgb, gwpara=2, ) multi.set_kmesh(**gw_kmesh) # Dataset 1 (GS run) multi[0].set_kmesh(**scf_kmesh) multi[0].set_vars(tolvrs=1e-6, nband=4) # Dataset 2 (NSCF run) multi[1].set_vars(iscf=-2, tolwfr=1e-10, nband=10, nbdbuf=2) # Dataset3: Calculation of the screening. multi[2].set_vars( optdriver=3, nband=8, ecutwfn=ecut, symchi=1, inclvkb=0, ecuteps=2.0, ) # Dataset4: Calculation of the Self-Energy matrix elements (GW corrections) kptgw = [ -2.50000000E-01, -2.50000000E-01, 0.00000000E+00, -2.50000000E-01, 2.50000000E-01, 0.00000000E+00, 5.00000000E-01, 5.00000000E-01, 0.00000000E+00, -2.50000000E-01, 5.00000000E-01, 2.50000000E-01, 5.00000000E-01, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, ] multi[3].set_vars( optdriver=4, nband=10, ecutwfn=ecut, ecuteps=2.0, ecutsigx=2.0, symsigma=1, #gw_qprange=0, ) bdgw = [4, 5] multi[3].set_kptgw(kptgw, bdgw) return multi.split_datasets()
def make_inputs(paw=False): # Crystalline silicon # Calculation of the GW correction to the direct band gap in Gamma # Dataset 1: ground state calculation # Dataset 2: NSCF calculation # Dataset 3: calculation of the screening # Dataset 4: calculation of the Self-Energy matrix elements (GW corrections) structure = abilab.Structure.from_file(abidata.cif_file("si.cif")) pseudos = abidata.pseudos("14si.pspnc") if not paw else abidata.pseudos("Si.GGA_PBE-JTH-paw.xml") multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=4) ecut = 14 multi.set_vars( ecut=ecut, pawecutdg=ecut*4 if paw else None, timopt=-1, istwfk="*1", paral_kgb=0, ) multi.set_kmesh( ngkpt=[6,6,6], shiftk=[0.0, 0.0, 0.0], ) gs, nscf, scr, sigma = multi.split_datasets() gs.set_vars(tolvrs=1e-6, nband=4,) # Dataset 2 (NSCF run) # Here we select the second dataset directly with the syntax inp[2] nscf.set_vars(iscf=-2, tolwfr=1e-8, nband=300, nbdbuf=50, ) # Dataset3: Calculation of the screening. scr.set_vars( optdriver=3, gwcalctyp=9, gwpara=2, nband=25, ecutwfn=ecut, symchi=1, awtr=2, inclvkb=0, ecuteps=4.0, spmeth=1, # Use Hilbert transform : Im chi0 --> chi0. nomegasf=250, # Number of points for Imchi0 nfreqre=50, nfreqim=10, freqremax="25 eV", freqremin="0 eV", ) # Dataset4: Calculation of the Self-Energy matrix elements (GW corrections) sigma.set_vars( optdriver=4, gwcalctyp=9, gwpara=2, nband=35, ecutwfn=ecut, ecuteps=4.0, ecutsigx=ecut, symsigma=1, gw_qprange=1, ) return gs, nscf, scr, sigma
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 = abilab.Flow(workdir, manager=options.manager, remove=options.remove) bands_work = abilab.BandStructureWork(scf_inp, nscf_inp) flow.register_work(bands_work) ddk_work = abilab.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 = abilab.OpticTask(optic_input, nscf_node=bands_work.nscf_task, ddk_nodes=ddk_work) flow.register_task(optic_task) return flow