-
Notifications
You must be signed in to change notification settings - Fork 1
/
QuantumESPRESSO.jl
117 lines (107 loc) · 3.59 KB
/
QuantumESPRESSO.jl
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
module QuantumESPRESSO
using AbInitioSoftwareBase.Inputs: setverbosity
using Crystallography: Cell, eachatom, cellvolume
using Distributed: LocalManager
using EquationsOfState.Collections
using OptionalArgChecks: @argcheck
using QuantumESPRESSO.Inputs: inputstring, optionof
using QuantumESPRESSO.Inputs.PWscf:
CellParametersCard, AtomicPositionsCard, PWInput, optconvert
using QuantumESPRESSO.Outputs.PWscf:
Preamble, parse_electrons_energies, parsefinal, isjobdone, tryparsefinal
using QuantumESPRESSO.CLI: PWCmd
using Setfield: @set!
using Unitful
using UnitfulAtomic
import ..EosFitting:
SelfConsistentField,
VariableCellOptimization,
preset_template,
_check_software_settings,
_expand_settings,
_readoutput
export safe_exit
function _check_software_settings(settings)
map(("manager", "bin", "n")) do key
@argcheck haskey(settings, key)
end
@argcheck isinteger(settings["n"]) && settings["n"] >= 1
if settings["manager"] == "docker"
@argcheck haskey(settings, "container")
elseif settings["manager"] == "ssh"
elseif settings["manager"] == "local" # Do nothing
else
error("unknown manager `$(settings["manager"])`!")
end
end # function _check_software_settings
const EosMap = (
m = Murnaghan,
bm2 = BirchMurnaghan2nd,
bm3 = BirchMurnaghan3rd,
bm4 = BirchMurnaghan4th,
v = Vinet,
)
function _expand_settings(settings)
template = parse(PWInput, read(expanduser(settings["template"]), String))
qe = settings["qe"]
if qe["manager"] == "local"
bin = qe["bin"]
manager = LocalManager(qe["n"], true)
elseif qe["manager"] == "docker"
n = qe["n"]
bin = qe["bin"]
# manager = DockerEnvironment(n, qe["container"], bin)
else
end
return (
template = template,
pressures = settings["pressures"] .* u"GPa",
trial_eos = EosMap[Symbol(settings["trial_eos"]["type"])](settings["trial_eos"]["parameters"] .*
uparse.(
settings["trial_eos"]["units"];
unit_context = [Unitful, UnitfulAtomic],
)...),
dirs = map(settings["pressures"]) do pressure
abspath(joinpath(
expanduser(settings["dir"]),
template.control.prefix,
"p" * string(pressure),
))
end,
bin = PWCmd(; bin = bin),
manager = manager,
)
end # function _expand_settings
function preset_template(calc, template)
template = setverbosity(template, "high")
@set! template.control.calculation = calc isa SelfConsistentField ? "scf" : "vc-relax"
@set! template.control.outdir = mktempdir()
return template
end
function _readoutput(::SelfConsistentField, s::AbstractString)
preamble = tryparse(Preamble, s)
e = try
parse_electrons_energies(s, :converged)
catch
nothing
end
if preamble !== nothing && e !== nothing
return preamble.omega * u"bohr^3" => e.ε[end] * u"Ry" # volume, energy
else
return
end
end # function _readoutput
function _readoutput(::VariableCellOptimization, s::AbstractString)
if !isjobdone(s)
@warn "Job is not finished!"
end
x = tryparsefinal(CellParametersCard, s)
if x !== nothing
return cellvolume(parsefinal(CellParametersCard, s)) * u"bohr^3" =>
parse_electrons_energies(s, :converged).ε[end] * u"Ry" # volume, energy
else
return
end
end
safe_exit(template::PWInput, dir) = touch(joinpath(dir, template.control.prefix * ".EXIT"))
end # module QuantumESPRESSO