diff --git a/src/ConvergenceTestWorkflow/Config.jl b/src/ConvergenceTestWorkflow/Config.jl index 4e6e433..839e643 100644 --- a/src/ConvergenceTestWorkflow/Config.jl +++ b/src/ConvergenceTestWorkflow/Config.jl @@ -1,9 +1,11 @@ module Config -using Configurations: OptionField, @option +using Configurations: OptionField using ExpressBase.Config: SoftwareConfig using QuantumESPRESSO.PWscf: PWInput +using ...QuantumESPRESSOExpress: QuantumESPRESSOConfig, MpiexecConfig, PwxConfig + import Configurations: from_dict import Express.ConvergenceTestWorkflow.Config: StaticConfig, _update! @@ -13,132 +15,6 @@ function _update!(conf, template::AbstractString) return conf end -@option struct MpiexecOptions <: SoftwareConfig - path::String = "mpiexec" - f::String = "" - hosts::Vector{String} = String[] - wdir::String = "" - configfile::String = "" - env::Union{Dict,Vector} = Dict(ENV) - np::UInt = 1 -end - -const MpiexecConfig = MpiexecOptions - -""" - ParallelizationFlags(; nimage=0, npool=0, ntg=0, nyfft=0, nband=0, ndiag=0) - -Construct parallelization flags of QuantumESPRESSO commands. -""" -@option mutable struct ParallelizationFlags - nimage::UInt = 0 - npool::UInt = 0 - ntg::UInt = 0 - nyfft::UInt = 0 - nband::UInt = 0 - ndiag::UInt = 0 -end - -""" - PwxConfig(; path, chdir, options) - -Create configurations for `pw.x`. - -# Arguments -- `path::String="pw.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `pw.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `pw.x`. -""" -@option mutable struct PwxConfig <: SoftwareConfig - path::String = "pw.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - PhxConfig(; path, chdir, options) - -Create configurations for `ph.x`. - -# Arguments -- `path::String="ph.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `ph.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `ph.x`. -""" -@option mutable struct PhxConfig <: SoftwareConfig - path::String = "ph.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - Q2rxConfig(; path, chdir, options) - -Create configurations for `q2r.x`. - -# Arguments -- `path::String="q2r.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `q2r.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `q2r.x`. -""" -@option mutable struct Q2rxConfig <: SoftwareConfig - path::String = "q2r.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - MatdynxConfig(; path, chdir, options) - -Create configurations for `matdyn.x`. - -# Arguments -- `path::String="matdyn.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `matdyn.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `matdyn.x`. -""" -@option mutable struct MatdynxConfig <: SoftwareConfig - path::String = "matdyn.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - DynmatxConfig(; path, chdir, options) - -Create configurations for `dynmat.x`. - -# Arguments -- `path::String="dynmat.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `dynmat.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `dynmat.x`. -""" -@option mutable struct DynmatxConfig <: SoftwareConfig - path::String = "dynmat.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end - -@option mutable struct QuantumESPRESSOConfig <: SoftwareConfig - mpi::MpiexecConfig = MpiexecConfig() - pw::PwxConfig = PwxConfig() - ph::PhxConfig = PhxConfig() - q2r::Q2rxConfig = Q2rxConfig() - matdyn::MatdynxConfig = MatdynxConfig() - dynmat::DynmatxConfig = DynmatxConfig() -end - function from_dict( ::Type{<:StaticConfig}, ::OptionField{:cli}, ::Type{SoftwareConfig}, dict ) diff --git a/src/EquationOfStateWorkflow/Config.jl b/src/EquationOfStateWorkflow/Config.jl index 00c42b2..b032444 100644 --- a/src/EquationOfStateWorkflow/Config.jl +++ b/src/EquationOfStateWorkflow/Config.jl @@ -1,9 +1,11 @@ module Config -using Configurations: OptionField, @option +using Configurations: OptionField using ExpressBase.Config: SoftwareConfig using QuantumESPRESSO.PWscf: PWInput +using ...QuantumESPRESSOExpress: QuantumESPRESSOConfig, MpiexecConfig, PwxConfig + import Configurations: from_dict import Express.EquationOfStateWorkflow.Config: StaticConfig, _update! @@ -13,132 +15,6 @@ function _update!(conf, template::AbstractString) return conf end -@option struct MpiexecOptions <: SoftwareConfig - path::String = "mpiexec" - f::String = "" - hosts::Vector{String} = String[] - wdir::String = "" - configfile::String = "" - env::Union{Dict,Vector} = Dict(ENV) - np::UInt = 1 -end - -const MpiexecConfig = MpiexecOptions - -""" - ParallelizationFlags(; nimage=0, npool=0, ntg=0, nyfft=0, nband=0, ndiag=0) - -Construct parallelization flags of QuantumESPRESSO commands. -""" -@option mutable struct ParallelizationFlags - nimage::UInt = 0 - npool::UInt = 0 - ntg::UInt = 0 - nyfft::UInt = 0 - nband::UInt = 0 - ndiag::UInt = 0 -end - -""" - PwxConfig(; path, chdir, options) - -Create configurations for `pw.x`. - -# Arguments -- `path::String="pw.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `pw.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `pw.x`. -""" -@option mutable struct PwxConfig <: SoftwareConfig - path::String = "pw.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - PhxConfig(; path, chdir, options) - -Create configurations for `ph.x`. - -# Arguments -- `path::String="ph.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `ph.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `ph.x`. -""" -@option mutable struct PhxConfig <: SoftwareConfig - path::String = "ph.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - Q2rxConfig(; path, chdir, options) - -Create configurations for `q2r.x`. - -# Arguments -- `path::String="q2r.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `q2r.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `q2r.x`. -""" -@option mutable struct Q2rxConfig <: SoftwareConfig - path::String = "q2r.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - MatdynxConfig(; path, chdir, options) - -Create configurations for `matdyn.x`. - -# Arguments -- `path::String="matdyn.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `matdyn.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `matdyn.x`. -""" -@option mutable struct MatdynxConfig <: SoftwareConfig - path::String = "matdyn.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end -""" - DynmatxConfig(; path, chdir, options) - -Create configurations for `dynmat.x`. - -# Arguments -- `path::String="dynmat.x"`: the path to the executable. -- `chdir::Bool=true`: whether to change directory to where the input file is - stored when running `dynmat.x`. If `false`, stay in the current directory. -- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization - flags of `dynmat.x`. -""" -@option mutable struct DynmatxConfig <: SoftwareConfig - path::String = "dynmat.x" - chdir::Bool = true - options::ParallelizationFlags = ParallelizationFlags() - env::Union{Dict,Vector} = Dict(ENV) -end - -@option mutable struct QuantumESPRESSOConfig <: SoftwareConfig - mpi::MpiexecConfig = MpiexecConfig() - pw::PwxConfig = PwxConfig() - ph::PhxConfig = PhxConfig() - q2r::Q2rxConfig = Q2rxConfig() - matdyn::MatdynxConfig = MatdynxConfig() - dynmat::DynmatxConfig = DynmatxConfig() -end - function from_dict( ::Type{<:StaticConfig}, ::OptionField{:cli}, ::Type{SoftwareConfig}, dict ) diff --git a/src/PhononWorkflow/Config.jl b/src/PhononWorkflow/Config.jl index 6261a6e..6283ead 100644 --- a/src/PhononWorkflow/Config.jl +++ b/src/PhononWorkflow/Config.jl @@ -1,34 +1,44 @@ module Config -using AbInitioSoftwareBase.Commands: MpiexecConfig using Configurations: OptionField -using Express.PhononWorkflow.Config: StaticConfig, Template +using Express.PhononWorkflow.Config: StaticConfig +using ExpressBase: + SelfConsistentField, + DensityFunctionalPerturbationTheory, + RealSpaceForceConstants, + PhononDispersion, + PhononDensityOfStates using ExpressBase.Config: SoftwareConfig -using QuantumESPRESSO.Commands: - QuantumESPRESSOConfig, PwxConfig, PhxConfig, Q2rxConfig, MatdynxConfig using QuantumESPRESSO.PWscf: PWInput using QuantumESPRESSO.PHonon: PhInput, Q2rInput, MatdynInput +using ...QuantumESPRESSOExpress: + MpiexecConfig, QuantumESPRESSOConfig, PwxConfig, PhxConfig, Q2rxConfig, MatdynxConfig + import Configurations: from_dict -import Express.PhononWorkflow.Config: ExpandConfig +import Express.PhononWorkflow.Config: StaticConfig, _update! -function (::ExpandConfig)(template::Template) - inputs = map( - (:scf, :dfpt, :q2r, :disp), (PWInput, PhInput, Q2rInput, MatdynInput) - ) do field, T - str = read(getproperty(template, field), String) - parse(T, str) +function _update!(conf, templates::Vector{String}) + stage, T = if conf.calculation isa SelfConsistentField + 1, PWInput + elseif conf.calculation isa DensityFunctionalPerturbationTheory + 2, PhInput + elseif conf.calculation isa RealSpaceForceConstants + 3, Q2rInput + elseif conf.calculation isa PhononDispersion + 4, MatdynInput + elseif conf.calculation isa PhononDensityOfStates + 4, MatdynInput + else + 4, DynmatInput end - return (; zip((:scf, :dfpt, :q2r, :disp), inputs)...) + str = read(templates[stage], String) + conf.template = parse(T, str) + return conf end function from_dict( - ::Type{<:StaticConfig}, ::OptionField{:cli}, ::Type{<:SoftwareConfig}, dict -) - return from_dict(StaticConfig, OptionField{:cli}(), QuantumESPRESSOConfig, dict) -end -function from_dict( - ::Type{<:StaticConfig}, ::OptionField{:cli}, ::Type{QuantumESPRESSOConfig}, dict + ::Type{<:StaticConfig}, ::OptionField{:cli}, ::Type{SoftwareConfig}, dict ) return QuantumESPRESSOConfig(; mpi=get(dict, "mpi", MpiexecConfig()), diff --git a/src/PhononWorkflow/actions.jl b/src/PhononWorkflow/actions.jl index 095138d..dc0fdc3 100644 --- a/src/PhononWorkflow/actions.jl +++ b/src/PhononWorkflow/actions.jl @@ -1,9 +1,12 @@ -using AbInitioSoftwareBase: Input, Setter, parentdir -using AbInitioSoftwareBase.Commands: MpiexecConfig +using AbInitioSoftwareBase: Input, Setter using Dates: format, now -using Express: Calculation, SCF -using Express.PhononWorkflow: DFPT, RealSpaceForceConstants, PhononDispersion, VDOS -# using QuantumESPRESSO: QuantumESPRESSOInput +using ExpressBase: + Calculation, + SelfConsistentField, + DensityFunctionalPerturbationTheory, + RealSpaceForceConstants, + PhononDispersion, + PhononDensityOfStates using QuantumESPRESSO.PWscf: PWInput, CellParametersCard, @@ -12,39 +15,36 @@ using QuantumESPRESSO.PWscf: AtomicPositionsCardSetter, tryparsefinal using QuantumESPRESSO.PHonon: PhInput, Q2rInput, MatdynInput, VerbositySetter, relayinfo -using QuantumESPRESSO.Commands: pw, ph, q2r, matdyn using Setfield: @set! using UnifiedPseudopotentialFormat # To work with `download_potential` -import Express.PhononWorkflow: CreateInput, RunCmd, parsecell, inputtype, buildjob - -inputtype(x::Calculation) = inputtype(typeof(x)) -inputtype(::Type{SCF}) = PWInput -inputtype(::Type{DFPT}) = PhInput -inputtype(::Type{RealSpaceForceConstants}) = Q2rInput -inputtype(::Type{<:Union{PhononDispersion,VDOS}}) = MatdynInput +import Express.PhononWorkflow: CreateInput, RunCmd, parsecell function parsecell(str) return tryparsefinal(AtomicPositionsCard, str), tryparsefinal(CellParametersCard, str) end -function (::CreateInput{SCF})(template::PWInput, args...) - return (customizer(args...) ∘ normalizer(SCF(), template))(template) +function (::CreateInput{SelfConsistentField})(template::PWInput, args...) + return (customizer(args...) ∘ normalizer(SelfConsistentField(), template))(template) end -function (::CreateInput{DFPT})(template::PhInput, previnp::PWInput) - return normalizer(DFPT(), previnp)(template) +function (::CreateInput{DensityFunctionalPerturbationTheory})( + template::PhInput, previnp::PWInput +) + return normalizer(DensityFunctionalPerturbationTheory(), previnp)(template) end function (::CreateInput{RealSpaceForceConstants})(template::Q2rInput, previnp::PhInput) return normalizer(RealSpaceForceConstants(), previnp)(template) end function (::CreateInput{T})( template::MatdynInput, a::Q2rInput, b::PhInput -) where {T<:Union{PhononDispersion,VDOS}} +) where {T<:Union{PhononDispersion,PhononDensityOfStates}} return normalizer(T(), (a, b))(template) end +(action::CreateInput)(template::MatdynInput, a::PhInput, b::Q2rInput) = + action(template, b, a) struct CalculationSetter <: Setter - calc::Union{SCF,DFPT} + calc::Union{SelfConsistentField,DensityFunctionalPerturbationTheory} end function (::CalculationSetter)(template::PWInput) @set! template.control.calculation = "scf" @@ -81,10 +81,11 @@ function (x::PseudoDirSetter)(template::PWInput) return template end -function normalizer(::SCF, args...) - return VerbositySetter("high") ∘ CalculationSetter(SCF()) ∘ PseudoDirSetter() +function normalizer(::SelfConsistentField, args...) + return VerbositySetter("high") ∘ CalculationSetter(SelfConsistentField()) ∘ + PseudoDirSetter() end -function normalizer(::DFPT, input::PWInput) +function normalizer(::DensityFunctionalPerturbationTheory, input::PWInput) return RelayArgumentsSetter(input) ∘ VerbositySetter("high") ∘ RecoverySetter() end normalizer(::RealSpaceForceConstants, input::PhInput) = RelayArgumentsSetter(input) @@ -93,7 +94,9 @@ function normalizer( ) return RelayArgumentsSetter(inputs) ∘ DosSetter(false) end -function normalizer(::VDOS, inputs::Union{Tuple{Q2rInput,PhInput},Tuple{PhInput,Q2rInput}}) +function normalizer( + ::PhononDensityOfStates, inputs::Union{Tuple{Q2rInput,PhInput},Tuple{PhInput,Q2rInput}} +) return RelayArgumentsSetter(inputs) ∘ DosSetter(true) end @@ -114,26 +117,6 @@ function (x::OutdirSetter)(template::PWInput) return template end -function customizer( - ap::AtomicPositionsCard, cp::CellParametersCard, timefmt::AbstractString="Y-m-d_H:M:S" -) - return OutdirSetter(timefmt) ∘ CellParametersCardSetter(cp) ∘ - AtomicPositionsCardSetter(ap) -end - -function (x::RunCmd{SCF})(input, output=mktemp(parentdir(input))[1]; kwargs...) - return pw(input, output; kwargs...) -end -function (x::RunCmd{DFPT})(input, output=mktemp(parentdir(input))[1]; kwargs...) - return ph(input, output; kwargs...) -end -function (x::RunCmd{RealSpaceForceConstants})( - input, output=mktemp(parentdir(input))[1]; kwargs... -) - return q2r(input, output; kwargs...) -end -function (x::RunCmd{<:Union{VDOS,PhononDispersion}})( - input, output=mktemp(parentdir(input))[1]; kwargs... -) - return matdyn(input, output; kwargs...) -end +customizer(ap::AtomicPositionsCard, cp::CellParametersCard) = + OutdirSetter("Y-m-d_H:M:S") ∘ CellParametersCardSetter(cp) ∘ + AtomicPositionsCardSetter(ap) diff --git a/src/QuantumESPRESSOExpress.jl b/src/QuantumESPRESSOExpress.jl index bded312..80c2a60 100644 --- a/src/QuantumESPRESSOExpress.jl +++ b/src/QuantumESPRESSOExpress.jl @@ -1,6 +1,13 @@ module QuantumESPRESSOExpress using AbInitioSoftwareBase: AbInitioSoftware +using ExpressBase: + SelfConsistentField, + VariableCellOptimization, + DensityFunctionalPerturbationTheory, + RealSpaceForceConstants, + PhononDispersion, + PhononDensityOfStates using ExpressBase.Files: parentdir # import Express: current_software @@ -13,12 +20,35 @@ const QE = QuantumESPRESSO currentsoftware() = QE() +include("SoftwareConfig.jl") include("ConvergenceTestWorkflow/ConvergenceTestWorkflow.jl") include("EquationOfStateWorkflow/EquationOfStateWorkflow.jl") -# include("PhononWorkflow/PhononWorkflow.jl") +include("PhononWorkflow/PhononWorkflow.jl") -function (x::RunCmd)(input, output=mktemp(parentdir(input))[1]; kwargs...) +function (x::RunCmd{SelfConsistentField})( + input, output=mktemp(parentdir(input))[1]; kwargs... +) return pw(input, output; kwargs...) end +function (x::RunCmd{VariableCellOptimization})( + input, output=mktemp(parentdir(input))[1]; kwargs... +) + return pw(input, output; kwargs...) +end +function (x::RunCmd{DensityFunctionalPerturbationTheory})( + input, output=mktemp(parentdir(input))[1]; kwargs... +) + return ph(input, output; kwargs...) +end +function (x::RunCmd{RealSpaceForceConstants})( + input, output=mktemp(parentdir(input))[1]; kwargs... +) + return q2r(input, output; kwargs...) +end +function (x::RunCmd{<:Union{PhononDensityOfStates,PhononDispersion}})( + input, output=mktemp(parentdir(input))[1]; kwargs... +) + return matdyn(input, output; kwargs...) +end end diff --git a/src/SoftwareConfig.jl b/src/SoftwareConfig.jl new file mode 100644 index 0000000..e030036 --- /dev/null +++ b/src/SoftwareConfig.jl @@ -0,0 +1,128 @@ +using Configurations: @option +using ExpressBase.Config: SoftwareConfig + +@option struct MpiexecOptions <: SoftwareConfig + path::String = "mpiexec" + f::String = "" + hosts::Vector{String} = String[] + wdir::String = "" + configfile::String = "" + env::Union{Dict,Vector} = Dict(ENV) + np::UInt = 1 +end + +const MpiexecConfig = MpiexecOptions + +""" + ParallelizationFlags(; nimage=0, npool=0, ntg=0, nyfft=0, nband=0, ndiag=0) + +Construct parallelization flags of QuantumESPRESSO commands. +""" +@option mutable struct ParallelizationFlags + nimage::UInt = 0 + npool::UInt = 0 + ntg::UInt = 0 + nyfft::UInt = 0 + nband::UInt = 0 + ndiag::UInt = 0 +end + +""" + PwxConfig(; path, chdir, options) + +Create configurations for `pw.x`. + +# Arguments +- `path::String="pw.x"`: the path to the executable. +- `chdir::Bool=true`: whether to change directory to where the input file is + stored when running `pw.x`. If `false`, stay in the current directory. +- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization + flags of `pw.x`. +""" +@option mutable struct PwxConfig <: SoftwareConfig + path::String = "pw.x" + chdir::Bool = true + options::ParallelizationFlags = ParallelizationFlags() + env::Union{Dict,Vector} = Dict(ENV) +end +""" + PhxConfig(; path, chdir, options) + +Create configurations for `ph.x`. + +# Arguments +- `path::String="ph.x"`: the path to the executable. +- `chdir::Bool=true`: whether to change directory to where the input file is + stored when running `ph.x`. If `false`, stay in the current directory. +- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization + flags of `ph.x`. +""" +@option mutable struct PhxConfig <: SoftwareConfig + path::String = "ph.x" + chdir::Bool = true + options::ParallelizationFlags = ParallelizationFlags() + env::Union{Dict,Vector} = Dict(ENV) +end +""" + Q2rxConfig(; path, chdir, options) + +Create configurations for `q2r.x`. + +# Arguments +- `path::String="q2r.x"`: the path to the executable. +- `chdir::Bool=true`: whether to change directory to where the input file is + stored when running `q2r.x`. If `false`, stay in the current directory. +- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization + flags of `q2r.x`. +""" +@option mutable struct Q2rxConfig <: SoftwareConfig + path::String = "q2r.x" + chdir::Bool = true + options::ParallelizationFlags = ParallelizationFlags() + env::Union{Dict,Vector} = Dict(ENV) +end +""" + MatdynxConfig(; path, chdir, options) + +Create configurations for `matdyn.x`. + +# Arguments +- `path::String="matdyn.x"`: the path to the executable. +- `chdir::Bool=true`: whether to change directory to where the input file is + stored when running `matdyn.x`. If `false`, stay in the current directory. +- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization + flags of `matdyn.x`. +""" +@option mutable struct MatdynxConfig <: SoftwareConfig + path::String = "matdyn.x" + chdir::Bool = true + options::ParallelizationFlags = ParallelizationFlags() + env::Union{Dict,Vector} = Dict(ENV) +end +""" + DynmatxConfig(; path, chdir, options) + +Create configurations for `dynmat.x`. + +# Arguments +- `path::String="dynmat.x"`: the path to the executable. +- `chdir::Bool=true`: whether to change directory to where the input file is + stored when running `dynmat.x`. If `false`, stay in the current directory. +- `options::ParallelizationFlags=ParallelizationFlags()`: the parallelization + flags of `dynmat.x`. +""" +@option mutable struct DynmatxConfig <: SoftwareConfig + path::String = "dynmat.x" + chdir::Bool = true + options::ParallelizationFlags = ParallelizationFlags() + env::Union{Dict,Vector} = Dict(ENV) +end + +@option mutable struct QuantumESPRESSOConfig <: SoftwareConfig + mpi::MpiexecConfig = MpiexecConfig() + pw::PwxConfig = PwxConfig() + ph::PhxConfig = PhxConfig() + q2r::Q2rxConfig = Q2rxConfig() + matdyn::MatdynxConfig = MatdynxConfig() + dynmat::DynmatxConfig = DynmatxConfig() +end