-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathexample_07.py
More file actions
executable file
·150 lines (128 loc) · 5.34 KB
/
Copy pathexample_07.py
File metadata and controls
executable file
·150 lines (128 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
"""Run a ``Wannier90BandsWorkChain`` for Wannier90 band structure with external projector.
Usage: ./example_07.py
"""
import json
import os
import click
from aiida import cmdline, orm
from aiida_wannier90_workflows.cli.params import RUN
from aiida_wannier90_workflows.common.types import WannierProjectionType
from aiida_wannier90_workflows.utils.code import check_codes, identify_codes
from aiida_wannier90_workflows.utils.structure import read_structure
from aiida_wannier90_workflows.utils.workflows.builder.serializer import print_builder
from aiida_wannier90_workflows.utils.workflows.builder.setter import set_parallelization
from aiida_wannier90_workflows.utils.workflows.builder.submit import (
submit_and_add_group,
)
from aiida_wannier90_workflows.workflows import Wannier90BandsWorkChain
def submit( # pylint: disable=too-many-positional-arguments
codes: dict,
structure: orm.StructureData,
pseudo_family: str,
external_projectors: dict,
external_projectors_path: str,
group: orm.Group = None,
run: bool = False,
):
"""Submit a ``Wannier90BandsWorkChain`` to calculate Wannier bands."""
builder = Wannier90BandsWorkChain.get_builder_from_protocol(
codes,
structure,
pseudo_family=pseudo_family,
projection_type=WannierProjectionType.ATOMIC_PROJECTORS_EXTERNAL,
external_projectors=external_projectors,
external_projectors_path=external_projectors_path,
protocol="fast",
)
# You can change parallelization here
parallelization = {
"num_mpiprocs_per_machine": 1,
"npool": 1,
}
set_parallelization(builder, parallelization, process_class=Wannier90BandsWorkChain)
print_builder(builder)
if run:
submit_and_add_group(builder, group)
def projectors_exists_check(computer, external_projectors_path):
"""Check whether external_projectors_path is valid on <computer>.
An additional check that external_projectors_path exists on compute node <computer>.
If exists, get projectors information and return.
When running HT calculations, we recommend locate the projectors on the <computer>,
but keep an addition ``projectors.json`` locally to facilitate workflow extracting information.
"""
local_compute = computer.transport_type == "core.local"
if local_compute:
external_projectors_path = os.path.abspath(external_projectors_path)
remote_path = orm.RemoteData(
computer=computer, remote_path=external_projectors_path
)
# Check if external_projectors_path exist on computer.
try:
list_projectors = remote_path.listdir()
except OSError as exc:
raise OSError(
f"{remote_path.get_remote_path()} is not a valid directory "
f"on computer<{computer.label}>"
) from exc
if not "projectors.json" in list_projectors:
if not local_compute:
transport_errormessage = (
f" and transport the projectors to computer<{computer.label}>"
)
else:
transport_errormessage = ""
raise FileNotFoundError(
f"Can not find projectors.json in ``{external_projectors_path}``. "
"Try to regenerate the external projector files referring to the script "
"``aiida-wannier90-workflows/dev/projectors/example_extend_aiida_pseudo.py``"
+ transport_errormessage
)
# Parse ``projectors.json``, if the file exists on remote computer, transport it to local as tmp file.
if not local_compute:
tmp_json_path = os.path.abspath("./tmp_projectors.json")
remote_path.getfile("./projectors.json", tmp_json_path)
with open(tmp_json_path, encoding="utf-8") as fp:
external_projectors = json.load(fp)
os.remove(tmp_json_path)
else:
with open(
external_projectors_path + "/projectors.json", encoding="utf-8"
) as fp:
external_projectors = json.load(fp)
return external_projectors, external_projectors_path
@click.command()
@cmdline.utils.decorators.with_dbenv()
@cmdline.params.options.CODES()
@cmdline.params.options.GROUP(help="The group to add the submitted workchain.")
@click.argument("filename", type=click.Path(exists=True))
@click.argument("pseudo_family", type=str)
@click.argument("external_projectors_path")
@RUN()
def cli(
filename, codes, pseudo_family, external_projectors_path, group, run
): # pylint: disable=too-many-positional-arguments
"""Run a ``Wannier90BandsWorkChain`` with external projectors.
FILENAME: a crystal structure file, e.g., ``input_files/GaAs.xsf``.
PSEUDO_FAMILY: label of pseudo family, e.g., ``SSSP/1.3/PBEsol/efficiency``.
EXTERNAL_PROJECTORS_PATH: the path to the directory on computing node which includes the external projectors.
e.g., ``input_files/external_projectors/``
"""
struct = read_structure(filename, store=True)
codes = identify_codes(codes)
check_codes(codes)
computer = codes["pw2wannier90"].computer
external_projectors, external_projectors_path = projectors_exists_check(
computer, external_projectors_path
)
submit(
codes,
struct,
pseudo_family,
external_projectors,
external_projectors_path,
group,
run,
)
if __name__ == "__main__":
cli() # pylint: disable=no-value-for-parameter