Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions doc/tutorials/Ce2O3_csc_w90/dft_input/ce2o3.win
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,8 @@ dos_kmesh = 50
!dos_smr_fixed_en_width = 0.05

begin projections
Ce1:l=3,mr=4:x=1,0,0
Ce1:l=3,mr=3:x=1,0,0
Ce1:l=3,mr=5:x=1,0,0
Ce1:l=3,mr=2:x=1,0,0
Ce1:l=3,mr=6:x=1,0,0
Ce1:l=3,mr=1:x=1,0,0
Ce1:l=3,mr=7:x=1,0,0
Ce2:l=3,mr=4:x=1,0,0
Ce2:l=3,mr=3:x=1,0,0
Ce2:l=3,mr=5:x=1,0,0
Ce2:l=3,mr=2:x=1,0,0
Ce2:l=3,mr=6:x=1,0,0
Ce2:l=3,mr=1:x=1,0,0
Ce2:l=3,mr=7:x=1,0,0
Ce1:l=3
Ce2:l=3
end projections

begin kpoints
Expand Down
13 changes: 11 additions & 2 deletions doc/tutorials/Ce2O3_csc_w90/dmft_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,27 @@ dc_dmft = true
calc_energies = true

h5_save_freq = 1
store_solver = false

[solver]
type = "hubbardI"
n_l = 15
store_solver = false
measure_G_l = false
measure_density_matrix = true

[dft]
dft_code = "qe"
n_cores = 10
mpi_env = "default"
mpi_exe = "mpirun"
projector_type = "w90"
dft_exec = "pw.x"
w90_tolerance = 1e-1

[dft.dft_exec]
path = '/path/to/q-e/bin'
pw = "pw.x -nk {number_cores}"
pw2wan = "pw2wannier90.x -nk 1 -pd .true."
bands = "bands.x -nk {number_cores}"
proj = "projwfc.x -nk {number_cores}"
win_pp = "wannier90.x -pp"
win = "wannier90.x"
23 changes: 18 additions & 5 deletions doc/tutorials/Ce2O3_csc_w90/tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,11 @@
"n_iter_dmft_per = 1\n",
"n_iter_dmft = 5\n",
"\n",
"enforce_off_diag = false\n",
"block_threshold = 1e-03\n",
"\n",
"h_int_type = \"density_density\"\n",
"h_int_basis = \"qe\"\n",
"U = 6.46\n",
"J = 0.46\n",
"beta = 10\n",
Expand All @@ -161,21 +163,30 @@
"calc_energies = true\n",
"\n",
"h5_save_freq = 1\n",
"store_solver = false\n",
"\n",
"[solver]\n",
"type = \"hubbardI\"\n",
"n_l = 15\n",
"store_solver = false\n",
"measure_G_l = false\n",
"measure_density_matrix = true\n",
"\n",
"[dft]\n",
"dft_code = \"qe\"\n",
"n_cores = 10\n",
"mpi_env = \"default\"\n",
"mpi_exe = \"mpirun\"\n",
"projector_type = \"w90\"\n",
"dft_exec = \"pw.x\"\n",
"w90_tolerance = 1.e-1\n"
"w90_tolerance = 1e-1\n",
"\n",
"[dft.dft_exec]\n",
"path = '/path/to/q-e/bin'\n",
"pw = \"pw.x -nk {number_cores}\"\n",
"pw2wan = \"pw2wannier90.x -nk 1 -pd .true.\"\n",
"bands = \"bands.x -nk {number_cores}\"\n",
"proj = \"projwfc.x -nk {number_cores}\"\n",
"win_pp = \"wannier90.x -pp\"\n",
"win = \"wannier90.x\"\n"
]
}
],
Expand All @@ -189,8 +200,10 @@
"metadata": {},
"source": [
"Of course you'll have to switch `csc` on to perform the charge self-consistent calculations. Then we choose the HubbardI Solver, set the number of Legendre polynomials, Matsubara frequencies $i\\omega_n$ and imaginary time grid points $\\tau$. In this calculation we perform five iterations in total, of which the two first ones are one-shot DMFT iterations, followed by three DFT and three DMFT steps.\n",
"For the interaction Hamiltonian we use `density_density`. Note that you unlike the Kanamori Hamiltonian, this one is not rotationally invariant, so the correct order of the orbitals must be set (inspect the projections card in `ce2o3.win`). We must also use `dc_dmft` and `calc_energies`, since we are interested in total energies.\n",
"Finally, we will specify some details for the DFT manager, i.e. to use QE, W90 and the tolerance for the mapping of shells. Note that this value should in general be $1e-6$, but for demonstration purposes we reduce it here. If `dft_exec` is empty, it will assume that `pw.x` and other QE executables are available."
"For the interaction Hamiltonian we use `density_density`. Unlike the Kanamori Hamiltonian this one is not rotationally invariant, so the interaction matrix must be built in the same cubic-harmonic convention as the Wannier projections. We therefore set `h_int_basis = \"qe\"` to match the Wannier90/QE convention and simply request the full $f$ shell with `Ce1:l=3` / `Ce2:l=3` in the projections card of `ce2o3.win`, which yields the orbitals in the natural Wannier90 order `mr=1..7`. Note that solid_dmft rotates the local problem into the local-Hamiltonian eigenbasis (`rot_mat_type='hloc_diag'`). We must also use `dc_dmft` and `calc_energies`, since we are interested in total energies.\n",
"Finally, we will specify some details for the DFT manager, i.e. to use QE, W90 and the tolerance for the mapping of shells. Note that this value should in general be $1e-6$, but for demonstration purposes we reduce it here. \n",
"\n",
"Here, we demonstarte how for QE `dft_exec` can be a dictionary in toml formatting style. You can very flexibly add custom commands for each part of the QE executables used if you like. You can also just simply write `dft_exec=/path/to/qe/bin/pw.x` and it will simply pick other executables for QE from there. If `dft_exec` is empty, it will assume that `pw.x` and other QE executables are available."
]
},
{
Expand Down
35 changes: 27 additions & 8 deletions python/solid_dmft/dft_managers/qe_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,22 @@ def run(number_cores, qe_file_ext, qe_exec, mpi_profile, mpi_exe_param, seedname

# get MPI env
hostfile = mpi_helpers.create_hostfile(number_cores, mpi_profile)
qe_exec_path = qe_exec.strip(qe_exec.rsplit('/')[-1])
qe_exec = qe_exec_path

valid_exec_keys = {"path", "pw", "pw2wan", "bands", "proj", "win_pp", "win"}
if isinstance(qe_exec, str):
qe_exec_path = os.path.dirname(qe_exec)
if qe_exec_path:
qe_exec_path += '/'
qe_select = {"path": qe_exec_path}
else:
assert "path" in qe_exec, "If dft_exec is not a string it must at least specify the path key"
unknown_keys = set(qe_exec.keys()) - valid_exec_keys
if unknown_keys:
raise ValueError(f"Unknown keys in dft_exec: {unknown_keys}. Valid keys: {valid_exec_keys}")
qe_select = qe_exec
qe_exec = qe_select.get("path", "")
if qe_exec and not qe_exec.endswith('/'):
qe_exec += '/'

if mpi.is_master_node():
# clean environment
Expand All @@ -115,17 +129,22 @@ def run(number_cores, qe_file_ext, qe_exec, mpi_profile, mpi_exe_param, seedname
print('\nMPI executable for QE:', mpi_exe)

if qe_file_ext in ['scf', 'nscf', 'mod_scf', 'bnd']:
qe_exec += f'pw.x -nk {number_cores}'
qe_exec += qe_select.get("pw", "pw.x -nk {number_cores}")
elif qe_file_ext in ['pw2wan']:
qe_exec += 'pw2wannier90.x -nk 1 -pd .true.'
qe_exec += qe_select.get("pw2wan", "pw2wannier90.x -nk 1 -pd .true.")
elif qe_file_ext in ['bands']:
qe_exec += f'bands.x -nk {number_cores}'
qe_exec += qe_select.get("bands", "bands.x -nk {number_cores}")
elif qe_file_ext in ['proj']:
qe_exec += f'projwfc.x -nk {number_cores}'
qe_exec += qe_select.get("proj", "projwfc.x -nk {number_cores}")
elif qe_file_ext in ['win_pp']:
qe_exec += 'wannier90.x -pp'
qe_exec += qe_select.get("win_pp", "wannier90.x -pp")
elif qe_file_ext in ['win']:
qe_exec += 'wannier90.x'
qe_exec += qe_select.get("win", "wannier90.x")

try:
qe_exec = qe_exec.format(**{**os.environ, "number_cores": number_cores})
except KeyError as e:
raise ValueError(f"Unknown placeholder {e} in dft_exec. Available: 'number_cores' and environment variables.") from None

arguments = mpi_helpers.get_mpi_arguments(mpi_profile, mpi_exe, number_cores, qe_exec, hostfile)
_start_with_piping(mpi_exe, arguments, qe_file_ext, env_vars, seedname)
Expand Down
18 changes: 16 additions & 2 deletions python/solid_dmft/io_tools/documentation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,22 @@ dft_code : string

* 'vasp'
* 'qe'
dft_exec : string, default = 'vasp_std'
command for the DFT executable
dft_exec : string or table, default = 'vasp_std'
command for the DFT executable. For VASP this is a simple string.
For QE this can be a string (path to QE executables) or a TOML table
``[dft.dft_exec]`` with per-executable overrides. Available keys:

* ``path`` — base path prepended to all executables (default: '')
* ``pw`` — pw.x command (default: 'pw.x -nk {number_cores}')
* ``pw2wan`` — pw2wannier90.x command (default: 'pw2wannier90.x -nk 1 -pd .true.')
* ``bands`` — bands.x command (default: 'bands.x -nk {number_cores}')
* ``proj`` — projwfc.x command (default: 'projwfc.x -nk {number_cores}')
* ``win_pp`` — wannier90.x preprocessing command (default: 'wannier90.x -pp')
* ``win`` — wannier90.x command (default: 'wannier90.x')

Use ``{number_cores}`` as a placeholder in commands, it will be replaced
with the value of ``n_cores``. Environment variables can be used the same
way, e.g. ``{HOME}`` or ``{SLURM_NTASKS}``, and are expanded at run time.
mpi_env : string, default = 'default'
selection for mpi env for DFT / VASP in default this will only call VASP as mpirun -np n_cores_dft dft_exec
Possible values:
Expand Down