Wannier90

For the source code, see wannier90.

Visualizing the WorkGraph Builder

[ ]:
from workgraph_collections.qe.wannier90_minimal import wannier90_minimal_workgraph
from aiida import load_profile
load_profile()

task = wannier90_minimal_workgraph.task()
task.to_html()

Visualizing the WorkGraph

[ ]:
from workgraph_collections.qe.wannier90_minimal import wannier90_minimal_workgraph
from aiida import load_profile
load_profile()

wg = wannier90_minimal_workgraph()
wg.to_html()

Example: GaAs band structure

Prepare the inputs and submit the workflow

[ ]:
from workgraph_collections.qe.wannier90_minimal import wannier90_minimal_workgraph
from aiida_wannier90.workflows.minimal import get_explicit_kpoints
from aiida import load_profile, orm
from copy import deepcopy
from aiida.plugins import DataFactory
from aiida_wannier90.orbitals import generate_projections

load_profile()

pw_code = orm.load_code("qe-7.2-pw@localhost")
pw2wannier90_code = orm.load_code("qe-7.2-pw2wannier90@localhost")
wannier90_code = orm.load_code("wannier90@localhost")

StructureData = DataFactory("core.structure")
a = 5.68018817933178
structure = StructureData(
    cell=[[-a / 2.0, 0, a / 2.0], [0, a / 2.0, a / 2.0], [-a / 2.0, a / 2.0, 0]]
)
structure.append_atom(symbols=["Ga"], position=(0.0, 0.0, 0.0))
structure.append_atom(symbols=["As"], position=(-a / 4.0, a / 4.0, a / 4.0))
structure.store()

# Load the pseudopotential family.
pseudo_family = orm.load_group("SSSP/1.3/PBEsol/efficiency")
pseudos = pseudo_family.get_pseudos(structure=structure)

scf_paras = {
    "CONTROL": {
        "calculation": "scf",
    },
    "SYSTEM": {
        "ecutwfc": 30,
        "ecutrho": 240,
    },
    "ELECTRONS": {},
}
nscf_paras = deepcopy(scf_paras)
nscf_paras["CONTROL"]["calculation"] = "nscf"
nscf_paras["SYSTEM"].update(
    {
        "nosym": True,
        "noinv": True,
    }
)
nscf_paras["ELECTRONS"].update({"startingpot": "file", "diago_full_acc": True})


scf_kpoints = orm.KpointsData()
scf_kpoints.set_kpoints_mesh([4, 4, 4])
# Use explicit list of kpoints generated by wannier.
# Since the QE auto generated kpoints might be different from wannier90, here we explicitly
# generate a list of kpoint coordinates to avoid discrepancies.
nscf_kpoints = orm.KpointsData()
nscf_kpoints.set_kpoints_mesh([10, 10, 10])
kpoints_nscf_explicit = get_explicit_kpoints(nscf_kpoints)
# If wannier inputs.kpoints is a kmesh, mp_grid will be auto-set by `Wannier90Calculation`,
# otherwise we need to set it manually. If use open_grid, kpoints will be set dynamically
# after open_grid calculation.
mp_grid = nscf_kpoints.get_kpoints_mesh()[0]

# k-points path for the band structure
kpoint_path = orm.Dict(
    {
        "point_coords": {
            "G": [0.0, 0.0, 0.0],
            "K": [0.375, 0.375, 0.75],
            "L": [0.5, 0.5, 0.5],
            "U": [0.625, 0.25, 0.625],
            "W": [0.5, 0.25, 0.75],
            "X": [0.5, 0.0, 0.5],
        },
        "path": [
            ("G", "X"),
            ("X", "U"),
            ("K", "G"),
            ("G", "L"),
            ("L", "W"),
            ("W", "X"),
        ],
    }
)
# sp^3 projections, centered on As
projections = generate_projections(
    {
        "position_cart": (-a / 4.0, a / 4.0, a / 4.0),
        "ang_mtm_l_list": -3,
        "spin": None,
        "spin_axis": None,
    },
    structure=structure,
)
#
metadata = {
    "options": {
        "resources": {
            "num_machines": 1,
            "num_mpiprocs_per_machine": 1,
        },
    }
}

# ===============================================================================

wannier_inputs = {
    "seekpath": {"structure": structure},
    "scf": {
        "code": pw_code,
        "pseudos": pseudos,
        "parameters": orm.Dict(scf_paras),
        "metadata": metadata,
        "kpoints": scf_kpoints,
    },
    "nscf": {
        "code": pw_code,
        "pseudos": pseudos,
        "parameters": orm.Dict(nscf_paras),
        "metadata": metadata,
        "kpoints": kpoints_nscf_explicit,
    },
    "wannier90_pp": {
        "code": wannier90_code,
        "parameters": orm.Dict(
            {
                "write_hr": False,
                "write_xyz": False,
                "use_ws_distance": True,
                "bands_plot": True,
                "num_iter": 200,
                "guiding_centres": False,
                "num_wann": 4,
                "exclude_bands": [1, 2, 3, 4, 5],
                "mp_grid": mp_grid,
            }
        ),
        "kpoints": kpoints_nscf_explicit,
        "kpoint_path": kpoint_path,
        "projections": projections,
        "metadata": metadata,
        "settings": orm.Dict({"postproc_setup": True}),
    },
    "pw2wannier90": {
        "code": pw2wannier90_code,
        "parameters": orm.Dict(
            {
                "inputpp": {
                    "write_mmn": True,
                    "write_amn": True,
                    "write_unk": True,
                },
            }
        ),
        "metadata": metadata,
    },
    "wannier90": {
        "code": wannier90_code,
        "parameters": orm.Dict(
            {
                "mp_grid": mp_grid,
                "write_hr": False,
                "write_xyz": False,
                "use_ws_distance": True,
                "bands_plot": True,
                "num_iter": 200,
                "guiding_centres": False,
                "num_wann": 4,
                "exclude_bands": [1, 2, 3, 4, 5],
            }
        ),
        "kpoints": kpoints_nscf_explicit,
        "kpoint_path": kpoint_path,
        "projections": projections,
        "metadata": metadata,
        "settings": orm.Dict({"postproc_setup": False}),
    },
}
wg = wannier90_minimal_workgraph(structure=structure, inputs=wannier_inputs)
wg.name = "Wannier-GaAs"
wg.run()

Bands WorkGraph

[ ]:
from workgraph_collections.qe.wannier90_bands import wannier90_workgraph
from aiida import load_profile
load_profile()

task = wannier90_workgraph.task()
task.to_html()

Visualizing the WorkGraph

[2]:
from workgraph_collections.qe.wannier90_bands import wannier90_bands_workgraph
from aiida import load_profile
load_profile()

wg = wannier90_bands_workgraph(bands_kpoints_distance=0.1)
wg.to_html()
[2]:

Example: GaAs band structure

Prepare the inputs and submit the workflow

[1]:
from workgraph_collections.qe.wannier90_bands import wannier90_bands_workgraph
from aiida import load_profile, orm
from copy import deepcopy
from aiida.plugins import DataFactory
from aiida_wannier90_workflows.utils.kpoints import (
            create_kpoints_from_distance,
            get_explicit_kpoints,
        )
from aiida_wannier90_workflows.utils.pseudo import (
            get_number_of_projections,
            get_pseudo_and_cutoff,
            get_wannier_number_of_bands,
        )
load_profile()

codes = {
"pw": orm.load_code("qe-7.2-pw@localhost"),
"projwfc": orm.load_code('qe-7.2-projwfc@localhost'),
"pw2wannier90": orm.load_code('qe-7.2-pw2wannier90@localhost'),
"wannier90": orm.load_code('wannier90@localhost'),
}

StructureData = DataFactory('core.structure')
a = 5.68018817933178
structure = StructureData(cell = [[-a/2., 0, a/2.], [0, a/2., a/2.], [-a/2., a/2., 0]])
structure.append_atom(symbols=['Ga'], position=(0., 0., 0.))
structure.append_atom(symbols=['As'], position=(-a/4., a/4., a/4.))
structure.store()

# Load the pseudopotential family.
pseudo_family = orm.load_group("SSSP/1.3/PBEsol/efficiency")
pseudos = pseudo_family.get_pseudos(structure=structure)
pseudos, _, _ = get_pseudo_and_cutoff("SSSP/1.3/PBEsol/efficiency", structure)
# INSULATOR
num_bands = get_wannier_number_of_bands(
            structure=structure,
            pseudos=pseudos,
            factor=1.2,
            only_valence=True,
            spin_polarized=False,
            spin_orbit_coupling=False,
        )
num_projs = get_number_of_projections(
    structure=structure,
    pseudos=pseudos,
    spin_orbit_coupling=False,
)
print("num_bands", num_bands)
print("num_projs", num_projs)
num_wann = num_bands # if insulator, num_wann = num_bands else num_wann = num_projs

scf_paras = {
    "CONTROL": {
        "calculation": "scf",
    },
    "SYSTEM": {
        "ecutwfc": 30,
        "ecutrho": 240,
        "occupations": "fixed",
    },
    "ELECTRONS": {}
}
nscf_paras = deepcopy(scf_paras)
nscf_paras['CONTROL']['calculation'] = 'nscf'
nscf_paras['SYSTEM'].update({'nosym': True,
                             'noinv': True,
                             'nbnd': num_bands})
nscf_paras['ELECTRONS'].update({'startingpot': 'file',
                                'diago_full_acc': True})


scf_kpoints = orm.KpointsData()
scf_kpoints.set_kpoints_mesh([2, 2, 2])
# Use explicit list of kpoints generated by wannier.
# Since the QE auto generated kpoints might be different from wannier90, here we explicitly
# generate a list of kpoint coordinates to avoid discrepancies.
kpoints = create_kpoints_from_distance(
            structure,
            distance=0.5,
            force_parity=False,
        )
wannier90_kpoints = get_explicit_kpoints(kpoints)
# If wannier inputs.kpoints is a kmesh, mp_grid will be auto-set by `Wannier90Calculation`,
# otherwise we need to set it manually. If use open_grid, kpoints will be set dynamically
# after open_grid calculation.
mp_grid = kpoints.get_kpoints_mesh()[0]

#
metadata = {
    "options": {
        "resources": {
            "num_machines": 1,
            "num_mpiprocs_per_machine": 4,
        },
    }
}

# ===============================================================================

inputs = {
    'seekpath': {"structure": structure},
    'scf': {
        'pw': {
            'pseudos': pseudos,
            'parameters': orm.Dict(scf_paras),
            'metadata': metadata,
        },
        'kpoints': scf_kpoints,
    },
    'nscf': {
        'pw': {
            'pseudos': pseudos,
            'parameters': orm.Dict(nscf_paras),
            'metadata': metadata,
        },
        'kpoints': wannier90_kpoints,
    },
    'projwfc': {
        'projwfc': {
            'metadata': metadata,
        }
    },
    'wannier90_pp': {
        'wannier90': {
            'parameters': orm.Dict({
                "auto_projections": True,
                "bands_plot": True,
                "conv_tol": 2.0e-05,
                "conv_window": 1,
                "dis_conv_tol": 2.0e-05,
                "dis_num_iter": 0,
                "num_cg_steps": 200,
                "num_iter": 400,
                "num_wann": num_wann,
                "num_bands": num_bands,
                "mp_grid": mp_grid,
            }),
            'kpoints': wannier90_kpoints,
            'metadata': metadata,
            'settings': orm.Dict({'postproc_setup': True}),
        },
    },
    'pw2wannier90': {
        'pw2wannier90': {
            "parameters": orm.Dict({
                "inputpp": {
                    "scdm_entanglement": "erfc",
                    "write_mmn": True,
                    "write_amn": True,
                    "write_unk": True,
                    "scdm_proj": True,
                },
            }),
            'metadata': metadata,
        }
    },
    'wannier90': {
        'wannier90': {
            'parameters': orm.Dict({
                "auto_projections": True,
                "bands_plot": True,
                "conv_tol": 2.0e-05,
                "conv_window": 1,
                "dis_conv_tol": 2.0e-05,
                "dis_num_iter": 0,
                "num_cg_steps": 200,
                "num_iter": 400,
                "num_wann": num_wann,
                "num_bands": num_bands,
                "mp_grid": mp_grid,
                }),
            'kpoints': wannier90_kpoints,
            'metadata': metadata,
            'settings': orm.Dict({'postproc_setup': False}),
        },
    },

}

wg = wannier90_bands_workgraph(structure=structure,
                               codes=codes,
                               inputs=inputs,
                               bands_kpoints_distance=0.1,
                               )
wg.name = "Wannier90-Bands-GaAs"
wg.submit()
wg.to_html()

num_bands 9
num_projs 13
WorkGraph process created, PK: 19813
[1]: