Skip to content

Commit

Permalink
Changed control_blocks to be more general for also allowing wannier inpu
Browse files Browse the repository at this point in the history
  • Loading branch information
louisponet committed Oct 17, 2017
1 parent 76d754c commit 4569bf9
Show file tree
Hide file tree
Showing 8 changed files with 2,002 additions and 101 deletions.
1,800 changes: 1,800 additions & 0 deletions assets/inputs/wannier/wan.win

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions notes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
TODO:
TODO:
->fix atom issue in file processing!
->redo all the Documentation!
->redo all the Documentation!

TODO:
-> maybe for every dfinput we should have an options category, not sure
1 change: 1 addition & 0 deletions src/DFControl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module DFControl
export read_qe_kpdos
export read_qe_input
export write_qe_input
export read_wannier_input
export write_df_input
export write_job_files

Expand Down
202 changes: 151 additions & 51 deletions src/file_processing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ function parse_k_line(line,T)
return [k1,k2,k3]
end
"""
Reads the output file of a 'bands' calculation in Quantum Espresso.
Returns an array of DFBands each with the same k_points and their respective energies.
read_qe_bands_file(filename::String, T=Float32)
Input: filename::String
Optional input: T=Float32 <: AbstractFloat (type of parsed floats)
Return: Array{DFBand{T},1}
Reads the output file of a 'bands' calculation in Quantum Espresso.
Returns an array of DFBands each with the same k_points and their respective energies.
"""
function read_qe_bands_file(filename::String, T=Float32)
f = open(filename)
Expand All @@ -22,7 +20,7 @@ function read_qe_bands_file(filename::String, T=Float32)
line = readline(f)
if contains(line,"celldm(1)")
alat_bohr = parse(T,split(line)[2])
prefac = T(2pi/alat_bohr * 1.889725)
prefac = T(2pi/alat_bohr * 1.889725)
end
if contains(line,"cryst.") && length(split(line))==2
line = readline(f)
Expand Down Expand Up @@ -77,7 +75,7 @@ function read_ks_from_qe_bands_file(filename::String,T=Float32)
line = readline(f)
if contains(line,"celldm(1)")
alat_bohr = parse(T,split(line)[2])
prefac = T(2pi/alat_bohr * 1.889725)
prefac = T(2pi/alat_bohr * 1.889725)
elseif contains(line,"cryst.") && length(split(line))==2
line = readline(f)
while line != ""
Expand All @@ -97,12 +95,10 @@ function read_ks_from_qe_bands_file(filename::String,T=Float32)
end

"""
Reads the Fermi level from a Quantum Espresso scf calculation output file
(if there is one).
read_fermi_from_qe_file(filename::String,T=Float32)
Input: filename::String
Optional input: T=Float32 <: AbstractFloat (type of parsed floats)
Return: T
Reads the Fermi level from a Quantum Espresso scf calculation output file
(if there is one).
"""
function read_fermi_from_qe_file(filename::String,T=Float32)
out = zero(T)
Expand All @@ -122,12 +118,13 @@ function read_fermi_from_qe_file(filename::String,T=Float32)
end

"""
read_qe_kpdos(filename::String,column=1;fermi=0)
Reads the k_resolved partial density of states from a Quantum Espresso projwfc output file.
Only use this if the flag kresolveddos=true in the projwfc input file!!
The returned matrix can be readily plotted using heatmap() from Plots.jl!
Input: filename::String
Optional input: column = 1 (column of the output, 1 = first column after ik and E)
fermi = 0 (possible fermi offset of the read energy values)
Return: Array{Float64,2}(length(k_points),length(energies)) ,
Expand All @@ -151,19 +148,11 @@ function read_qe_kpdos(filename::String,column=1;fermi=0)
end


#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#Incomplete for now only allows for 1 atom of the same kind!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""
Reads a Quantum Espresso input file.
Returns a DFInput.
read_qe_input(filename,T=Float32)
Input: filename::String
Optional input: T=Float32 <: AbstractFloat (type of parsed floats)
Return: DFInput{T}
Reads a Quantum Espresso input file.
Returns a DFInput.
"""
function read_qe_input(filename,T=Float32)
function get_card_option(line,length)
Expand All @@ -174,7 +163,7 @@ function read_qe_input(filename,T=Float32)
pseudos = Dict{Symbol,String}()
atoms = Dict{Symbol,Array{<:Point3D,1}}()
k_dict = Dict{Symbol,Any}()

open(filename) do f
while !eof(f)
line = readline(f)
Expand Down Expand Up @@ -208,8 +197,8 @@ function read_qe_input(filename,T=Float32)
end
control_blocks[block_symbol]=tmp_dict
@goto startlabel


elseif contains(line,"CELL_PARAMETERS")||contains(line,"cell_parameters")
cell_unit = get_card_option(line,15)
cell = Matrix{T}(3,3)
Expand All @@ -226,9 +215,9 @@ function read_qe_input(filename,T=Float32)
pseudos[Symbol(split(line)[1])] = split(line)[end]
line = readline(f)
end
@goto startlabel

@goto startlabel

#TODO fix that atoms can only be fractional!
elseif contains(line,"ATOMIC_POSITIONS")||contains(line,"atomic_positions")
pos_unit = get_card_option(line,16)
line = readline(f)
Expand All @@ -243,7 +232,7 @@ function read_qe_input(filename,T=Float32)
end
line = readline(f)
end
@goto startlabel
@goto startlabel

elseif contains(line,"K_POINTS")||contains(line,"k_points")
k_option = get_card_option(line,8)
Expand All @@ -260,7 +249,7 @@ function read_qe_input(filename,T=Float32)
end
k_dict[:points] = k_point_array
end
@goto startlabel
@goto startlabel
end

end
Expand All @@ -269,12 +258,10 @@ function read_qe_input(filename,T=Float32)
end


# change atom writing!
"""
Writes a Quantum Espresso input file.
write_qe_input(filename::String,df_input::DFInput)
Input: filename::String,
df_input::DFInput
Writes a Quantum Espresso input file.
"""
function write_qe_input(filename::String,df_input::DFInput)
if df_input.backend != :QE
Expand All @@ -291,12 +278,12 @@ function write_qe_input(filename::String,df_input::DFInput)
end
write(f,"/\n\n")
end

#write the other cards depending on whether or not they are there
if !isempty(df_input.atoms)
write(f,"ATOMIC_SPECIES\n")
for atom in keys(df_input.atoms)
#@Incomplete Once default pseudos are implemented put it in the default slot here!!!!!
#@Incomplete Once default pseudos are implemented put it in the default slot here!!!!!
pseudo = get(df_input.pseudos,atom,"PUT PSEUDO HERE")
write(f,"$(String(atom)) $(Float32(ELEMENTS[atom].atomic_weight)) $pseudo\n")
end
Expand All @@ -312,7 +299,7 @@ function write_qe_input(filename::String,df_input::DFInput)
write(f,"$(cell[3,1]) $(cell[3,2]) $(cell[3,3])\n")
write(f,"\n")
end

if !isempty(df_input.atoms)
write(f,"ATOMIC_POSITIONS (crystal)\n")
for (atom,points) in df_input.atoms
Expand All @@ -322,12 +309,12 @@ function write_qe_input(filename::String,df_input::DFInput)
end
write(f,"\n")
end

if !isempty(df_input.k_points)
k_option = df_input.k_points[:option]
write(f,"K_POINTS ($k_option)\n")

if k_option == :automatic
if k_option == :automatic
write(f,"$(df_input.k_points[:nk1]) $(df_input.k_points[:nk2]) $(df_input.k_points[:nk2]) $(df_input.k_points[:sk1]) $(df_input.k_points[:sk2]) $(df_input.k_points[:sk3])\n")
elseif k_option == :crystal_b
points = df_input.k_points[:points]
Expand All @@ -350,11 +337,10 @@ end

#@Incomplete: does not read wan input files now
"""
Reads a job file and all the mentioned Quantum Espresso input files.
Returns an array of String pairs that are (calculation,input_file)
read_qe_inputs_from_job_file(job_file)
Input: job_file::String
Return: Array{Tuple{String,String},1}()
Reads a job file and all the mentioned Quantum Espresso input files.
Returns an array of String pairs that are (calculation,input_file)
"""
function read_qe_inputs_from_job_file(job_file)
inputs = Array{Tuple{String,String},1}()
Expand All @@ -372,13 +358,127 @@ function read_qe_inputs_from_job_file(job_file)
return inputs
end
#---------------------------END QUANTUM ESPRESSO SECTION----------------#
#---------------------------START WANNIER SECTION ----------------------#

#We also use DFInput to store wannier input, the non-named block in wannier is stored in the :control
#dictionary.
function read_wannier_input(filename::String, T=Float32)
strip_split(line,args...) = strip.(split(line,args...))
control_blocks = Dict{Symbol,Any}()
control_blocks[:control] = Dict{Symbol,Any}()
atoms = Dict{Symbol,Union{Symbol,Array{Point3D{T},1}}}()
k_points = Dict{Symbol,Array{T,1}}()
cell_param_dict = Dict{Symbol,Matrix{T}}()
open(filename,"r") do f
while !eof(f)
line = readline(f)
if contains(line,"!")||line==""
continue
end
if contains(line,"Begin") || contains(line,"begin")
block_name = Symbol(lowercase(split(line)[end]))
line = readline(f)

if block_name == :projections
if line == "random"
control_blocks[block_name] = Dict(:random=>Symbol[])
else
proj_dict = Dict{Symbol,Array{Symbol,1}}()
while !(contains(line,"End") || contains(line,"end"))
if contains(line,"!")
line = readline(f)
continue
end
split_line = strip_split(line,':')
atom = Symbol(split_line[1])
projections = [Symbol(proj) for proj in strip_split(split_line[2],';')]
proj_dict[atom] = projections
line = readline(f)
end
control_blocks[block_name] = proj_dict
end
elseif block_name == :kpoint_path
k_path_array = Array{Tuple{Symbol,Array{T,1}},1}()
while !(contains(line,"End") || contains(line,"end"))
if contains(line,"!")
line = readline(f)
continue
end
split_line = split(line)
push!(k_path_array,(Symbol(split_line[1]),parse_string_array(T,split_line[2:4])))
push!(k_path_array,(Symbol(split_line[5]),parse_string_array(T,split_line[6:8])))
line = readline(f)
end
control_blocks[block_name] = k_path_array
elseif block_name == :unit_cell_cart
if length(split(line)) == 1
option = Symbol(lowercase(line))
else
option = :ang
end
cell_param = Matrix{T}(3,3)
for i=1:3
cell_param[i,:] = parse_line(T,readline(f))
end
cell_param_dict[option] = cell_param
line = readline(f)

elseif block_name ==:atoms_frac || block_name == :atoms_cart
atoms[:option] = block_name
while !(contains(line,"end") || contains(line,"End"))
split_line = strip_split(line)
atom = Symbol(split_line[1])
position = Point3D(parse_string_array(T,split_line[2:4]))
if !haskey(atoms,atom)
atoms[atom] = [position]
else
push!(atoms[atom],position)
end
line = readline(f)
end

elseif block_name == :kpoints
i=1
while !(contains(line,"end") || contains(line,"End"))
k_points[Symbol(i)] = parse_line(T,line)
line = readline(f)
i+=1
end
end

else
if contains(line,"mp_grid")
control_blocks[:control][:mp_grid] = parse_string_array(Int,split(split(line,'=')[2]))
else
split_line = strip_split(line,'=')
flag = Symbol(split_line[1])
value = split_line[2]
if lowercase(value)=="t" || lowercase(value) == "true"
control_blocks[:control][flag] = true
elseif lowercase(value) == "f" || lowercase(value) == "false"
control_blocks[:control][flag] = false
elseif !isnull(tryparse(Int,value))
control_blocks[:control][flag] = get(tryparse(Int,value))
elseif !isnull(tryparse(T,value))
control_blocks[:control][flag] = get(tryparse(T,value))
else
control_blocks[:control][flag] = value
end
end
end
end
end
return DFInput(:wannier,control_blocks,Dict{Symbol,String}(),cell_param_dict,atoms,k_points)
end


#---------------------------END WANNIER SECTION ------------------------#
#---------------------------BEGINNING GENERAL SECTION-------------------#
"""
write_df_input(filename::String,df_input::DFInput)
Writes the input file for a DFInput.
Backend of DFInput decides what writing function is called.
Input: filename::String,
df_input::DFInput
"""
function write_df_input(filename::String,df_input::DFInput)
if df_input.backend == :QE
Expand All @@ -394,9 +494,9 @@ end
#@Incomplete there might be the case that we want multiple different nscf or scf or whatever inputs. Maybe using array of tuple(string,dfinput)
# would be more suitable
"""
Writes all the input files and job file that are linked to a DFJob.
write_job_files(df_job::DFJob)
input: df_job::DFJob
Writes all the input files and job file that are linked to a DFJob.
"""
function write_job_files(df_job::DFJob)
files_to_remove = search_dir(df_job.home_dir,".in")
Expand All @@ -409,7 +509,7 @@ function write_job_files(df_job::DFJob)
filename = "$i"*df_job.job_name*"_$input"*".in"
push!(new_filenames,filename)
write_df_input(df_job.home_dir*filename,df_job.calculations[input])
write(f,"mpirun -np 24 $run_command <$filename> $(split(filename,".")[1]).out \n")
write(f,"mpirun -np 24 $run_command <$filename> $(split(filename,".")[1]).out \n")
end
end

Expand All @@ -420,4 +520,4 @@ function write_job_files(df_job::DFJob)
end
end

#---------------------------END GENERAL SECTION-------------------#
#---------------------------END GENERAL SECTION-------------------#
Loading

0 comments on commit 4569bf9

Please sign in to comment.