Skip to content

Commit

Permalink
include literate docs
Browse files Browse the repository at this point in the history
  • Loading branch information
louisponet committed Jun 16, 2021
1 parent bdde5dd commit a5b2ea9
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 3 deletions.
6 changes: 3 additions & 3 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ build/
site/
src/examples/*.md
src/examples/*.ipynb
src/guide/advanced_tutorial.jl
src/guide/advanced_tutorial.ipynb
src/guide/basic_tutorial.jl
src/guide/basic_tutorial.md
src/guide/advanced_tutorial.md
src/guide/basic_tutorial.ipynb
src/guide/advanced_tutorial.ipynb
69 changes: 69 additions & 0 deletions docs/src/guide/advanced_tutorial.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# # Advanced Usage
# In this tutorial we will continue from the job created in the [Basic Tutorial](@ref),
# and demonstrate some more advanced functionality that DFControl offers.

# To load a previously saved job we here provide a valid job directory with a job.tt script
# in it.
using DFControl

tjob = DFJob(joinpath(@__DIR__, "../assets/job/"))#hide
tjob2 = DFJob(joinpath(@__DIR__, "../assets/job/Job2"))#hide
try#hide
job = DFJob(pwd())
catch#hide
global job = deepcopy(tjob)#hide
set_localdir!(job, pwd()); #hide
job#hide
end#hide

# Since the job was saved in the current working directory this will work, see the section on [Jobs](@ref) for
# further details and options on how to load previously saved jobs.

# The next thing we may want to do is to change the directory where the job is running.
set_localdir!(job, "Job2", copy=true)
# With the `copy=true` flag we let DFControl know that not only to create and set the
# new directory, but also to copy the previous results and temporary files to the
# new directory so we don't have to rerun the scf calculation.

# Next we would like to plot the projected density of states.
# For that we create both an nscf calculation to get a uniform k-grid, and projwfc input.
push!(job, gencalc_nscf(job["scf"], (6,6,6)))

# The second argument of gencalc_nscf is the kgrid. When passing a 3-Tuple,
# the code will assume that an explicit k-grid is requested, which can be verified by
data(job["nscf"], :k_points)

# Next we generate a projwfc input using the fermi level as a guide for the
# energy window.
# The arguments are structured as (template, Emin, Emax, deltaE) respectively.
fermi = readfermi(job)
push!(job, gencalc_projwfc(job["nscf"], fermi-10, fermi+1, 0.1))
# Next we disable the bands calculation, run the new ones, and plot the results
job["bands"].run = false
try#hide
submit(job)
catch#hide
global job = deepcopy(tjob2)#hide
end#hide
using Plots
plot(job, -10, 1)

# As we can see, again DFControl identifies the additional information that is now present in the job, and uses it
# to display in the plot.

# In the demonstrated case we see that everything went according to plan, however, often things need to be changed
# in a trial and error way until the desired results are found.

# On common occurence is that input flags have to be set, or changed. This can be done in two ways
job[:ecutwfc] = 40.0
# will go through all the inputs of the job and set the flag if it is allowed, i.e. the flag will not
# be set in the projwfc input since it makes no sense.
job["bands"][:nbnd] = 30
# This will set a flag for one specific calculation, again checking whether the flag is valid, and the type
# will be converted to the correct one.

# In order to quickly specify what calculations to schedule and which not, one can use
set_flow!(job, "" => false, "scf" => true)
# As we can see, only the scf and nscf calculations are scheduled to run now,
# this is because for each of the pairs in the arguments of `set_flow!`, every input inside
# the job for which the string occurs in the name will be set to run or not depending on the Bool.
116 changes: 116 additions & 0 deletions docs/src/guide/basic_tutorial.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# # Basic Tutorial

# Since DFControl is aimed at improving the day to day quality of life of a material's scientist/anyone running DFT codes,
# we will look at a simple demonstration of how by creating and submitting some
# [Quantum-Espresso](https://www.quantum-espresso.org/) calculations on Si
# starting from a cif file specifying the structure.

using DFControl

# First we download the cif file, extract the `Structure` and assign the right pseudos to it.
# In this case Si (F d -3 m :1) from http://www.crystallography.net/cod/9011998.cif
using Downloads
cif_file = Downloads.download("http://www.crystallography.net/cod/9011998.cif", "Si.cif")

structure = Structure(cif_file, name="Si")
set_pseudos!(structure, :pbesol)

# This assumes that the `:pbesol` pseudopotential set was installed during the
#md # [configuration step](@ref Configuration).

# Next we specify the executables with which to run the QE calculations.
# We assume here that `mpirun` is installed and in the user's PATH, and that
# QE is installed, and to be found in the `/opt/qe/bin`, change this according to your own
# setup.

pw_execs = [Exec("mpirun", "", :np => 4), Exec("pw.x", "/opt/qe/bin/", :nk => 4)]

# Additional executable flags can be passed as varargs to the constructor of `Exec`,
# e.g. `Exec("pw.x", "/opt/qe/bin/", :nk => 4, :ndiag => 2)`.

# Then we create the first input for our job, we name it scf, which will be used to reference it later.
# We also pass the executables to be used and additional flags to be set to the constructor.
# Afterwards we set the kpoints to be used in the scf calculation.
scf_input = DFInput{QE}("scf", pw_execs, :calculation => "scf")
set_kpoints!(scf_input, (6,6,6,1,1,1))

# The code recognizes internally that this 6-Tuple corresponds to a
# `K_POINTS (automatic)` block in QE. Alternatively (leading to an identical final result):

scf_input = DFInput{QE}("scf", pw_execs, :calculation => "scf",
data=[InputData(:k_points, :automatic, (6,6,6,1,1,1))])

# We can now define our job:
job = DFJob("Si", structure, [scf_input],
:ecutwfc => 20,
:conv_thr => 1e-6)

# Additional inputs would be be added to the list `[scf_input]`.
# The flag => value pairs will set the specified flags to that value for all inputs in the job
# that allow recognize that flag, so it's ideal for things like cutoffs and smearing etc.

# We are now ready to submit the job, which will run in the current working directory
try #hide
submit(job)
catch #hide
global job = DFJob(joinpath(@__DIR__, "../assets/job/"))#hide
pop!(job); #hide
end #hide

# This will generate and save all input files, and the corresponding job script (`job.tt`),
# and subsequently run the job.
# First submission through `sbatch job.tt` will be tried, if that fails then the script will run
# through `bash job.tt`.

# After the job finishes the outputs can be parsed through
outputdata(job)
# or for a specific calculation
outputdata(job["scf"])

# This also demonstrates how a calculation can be referenced using its name
# (remember that we named the calculation "scf" when creating it).

# Now that the scf calculation finished succesfully, the next step is usually to
# have a look at the bandstructure. For this we generate a bands calculation,
# using the scf calculation as a template and a generated high symmetry k-point path
# with 20 kpoints per segment.

bands_calc = gencalc_bands(job["scf"], high_symmetry_kpath(job.structure, 20))

# Observe the :calculation => "bands", and automatic setting of the :verbosity => "high" flags.
# We now push! this calculation to the job queue
push!(job, bands_calc)

# However, since we know the scf succeeded there is no need to rerun it.
# To un-schedule it we do
job["scf"].run = false

# Printing the job will now highlight the scheduled calculations differently from the non-scheduled ones
job

# Seeing that all is right we submit the job again
set_localdir!(job, pwd()); #hide
try #hide
submit(job)
catch #hide
global job = DFJob("/home/ponet/.julia/dev/DFControl/docs/src/assets/job/");#hide
end #hide

# We can access the bands through
bands = readbands(job);
# or
bands = outputdata(job["bands"])[:bands];

# They can be plotted too
fermi = readfermi(job) # = outputdata(job["scf"])[:fermi]
using Plots
plot(bands, fermi=fermi)

# Since more info (such as the structure) is available in the job,
# plotting the job leads to a richer plot
plot(job, -10, 1)
# where -10, 1 designates the energy window for the plot.

# As can be seen in the [Advanced Usage](@ref), additional information
# generated by additional calculations will be picked up by DFControl
# in order to create richer plots.

0 comments on commit a5b2ea9

Please sign in to comment.