aton.api.phonopy
Description
Functions to work with Phonopy calculations, along with Quantum ESPRESSO.
Index
make_supercells() |
Build supercell SCF inputs for phonon calculations |
Examples
To create the 2x2x2 supercells and run the phonon calculations
from a folder with relax.in and relax.out files,
using a template.slurm file,
from aton import api
api.phonopy.make_supercells('relax.in', 'relax.out')
api.slurm.sbatch('supercell-', 'template.slurm')
1""" 2# Description 3 4Functions to work with [Phonopy](https://phonopy.github.io/phonopy/) calculations, 5along with [Quantum ESPRESSO](https://www.quantum-espresso.org/). 6 7 8# Index 9 10| | | 11| --- | --- | 12| `make_supercells()` | Build supercell SCF inputs for phonon calculations | 13 14 15# Examples 16 17To create the 2x2x2 supercells and run the phonon calculations 18from a folder with `relax.in` and `relax.out` files, 19using a `template.slurm` file, 20```python 21from aton import api 22api.phonopy.make_supercells('relax.in', 'relax.out') 23api.slurm.sbatch('supercell-', 'template.slurm') 24``` 25 26--- 27""" 28 29 30import os 31from aton._version import __version__ 32import aton.file as file 33import aton.call as call 34import aton.txt.find as find 35import aton.txt.edit as edit 36import aton.txt.extract as extract 37import aton.api.pwx as pwx 38import aton.api.slurm as slurm 39import shutil 40import scipy.constants as const 41 42 43def make_supercells( 44 relax_in:str='relax.in', 45 relax_out:str='relax.out', 46 scf:str=None, 47 slurm_template:str='template.slurm', 48 folder:str=None, 49 dimension:str='2 2 2', 50 amplitude:float=None, 51 update:dict=None, 52 update_E:bool=True, 53 ) -> None: 54 """ 55 Creates and prepares the supercell inputs of Phonopy, 56 57 These supercells are created from the `relax_in` and `relax_out` files in the `folder` 58 ('relax.in', 'relax.out' and CWD by default, respectively), 59 needed for the Phonopy calculations with Quantum ESPRESSO. 60 Alternatively, a previously relaxed `scf` input file can be provided, 61 which will override the creation of a new scf file 62 from the `relax_in` and `relax_out` files. 63 The cells have a given `dimension` ('2 2 2' by default), 64 and the displacement `amplitude` is set to phonopy's default unless specified. 65 66 Extensive convergence values for the energy (`etot_conv_thr` and `conv_thr`) 67 are updated automatically according to the supercell size. 68 This can be disabled with `update_E=False`. 69 Any input value can be updated with an `update` dict, 70 overriding automatic values. 71 72 By default, at the end of the execution it will check 73 that an `slurm_template` ('template.slurm') is present and valid; 74 this is, containing the keywords `JOBNAME`, `INPUT` and `OUTPUT`. 75 If not, an example with instructions will be provided. 76 This check can be skipped with `slurm_template=''`. 77 The template will allow to easily run the Phonopy calculations with the one-line command 78 `aton.api.slurm.sbatch('supercell-', 'template.slurm')`. 79 """ 80 print(f'\nWelcome to aton.api.phonopy {__version__}\n' 81 'Creating all supercell inputs with Phonopy for Quantum ESPRESSO...\n') 82 if not scf: 83 pwx.scf_from_relax(folder, relax_in, relax_out, update=update) 84 scf = 'scf.in' 85 _check_dims = extract.coords(dimension) 86 if len(_check_dims) != 3: 87 raise ValueError('Supercell dimension must be given as "nx ny nz"!') 88 _supercells_from_scf(folder, scf, dimension, amplitude) 89 _copy_scf_header_to_supercells(folder, scf, update, update_E) 90 print('\n------------------------------------------------------\n' 91 'PLEASE CHECH BELOW THE CONTENT OF supercell-001.in\n' 92 '------------------------------------------------------\n') 93 call.bash('head -n 100 supercell-001.in') 94 print('\n------------------------------------------------------\n' 95 'PLEASE CHECH THE CONTENT OF supercell-001.in\n' 96 'The first 100 lines of the input were printed above!\n' 97 '------------------------------------------------------\n\n' 98 'If it seems correct, run the calculations with:\n' 99 f"aton.api.slurm.sbatch('supercell-', '{slurm_template}')\n") 100 if slurm_template: 101 slurm.check_template(slurm_template, folder) 102 return None 103 104 105def _supercells_from_scf( 106 folder:str=None, 107 scf:str='scf.in', 108 dimension:str='2 2 2', 109 amplitude:float=None, 110 ) -> None: 111 """ 112 Creates supercells of a given `dimension` (`2 2 2` by default) inside a `folder`, 113 from a Quantum ESPRESSO `scf` input (`scf.in` by default). 114 """ 115 folder = call.here(folder) 116 scf_in = file.get(folder, scf, True) 117 scf_temp1 = _ensure_bohr_units(folder, scf_in) 118 if scf_temp1 is None: 119 raise FileNotFoundError('No SCF input found in path!') 120 if amplitude: 121 call.bash(f'phonopy --qe -d --dim="{dimension}" --amplitude="{amplitude}" -c {scf_temp1}') 122 else: 123 call.bash(f'phonopy --qe -d --dim="{dimension}" -c {scf_temp1}') 124 os.remove(scf_temp1) 125 return None 126 127 128def _ensure_bohr_units(folder:str=None, scf:str='scf.in') -> None: 129 """Check that the lattice units are bohr instead of angstrom in the `scf` input file.""" 130 folder = call.here(folder) 131 scf_in = file.get(folder, scf, True) 132 scf_temp1 = '_temp_scf_in_bohr_units.in' 133 shutil.copy(scf_in, scf_temp1) 134 input_values = pwx.read_in(scf_in) 135 if 'A' in input_values: # Convert angstrom to bohr 136 celldm = input_values['A'] / (const.physical_constants['Bohr radius'][0] * 1e10) 137 pwx.set_value(scf_temp1, 'celldm(1)', celldm) 138 print(f'Updated celldm(1) from A: {input_values["A"]} AA -> {celldm} bohr') 139 return scf_temp1 140 141 142def _copy_scf_header_to_supercells( 143 folder:str=None, 144 scf:str='scf.in', 145 update:dict=None, 146 update_E:bool=True, 147 ) -> None: 148 """Paste the header from the `scf` file in `folder` to the supercells created by Phonopy.""" 149 print(f'Creating header...\n') 150 folder = call.here(folder) 151 # Check if the header file, the scf.in, exists 152 scf_file = file.get(folder, scf, True) 153 if scf_file is None: 154 raise FileNotFoundError('No header file found in path!') 155 # Check if the supercells exist 156 supercells = file.get_list(folder, include='supercell-') 157 if supercells is None: 158 raise FileNotFoundError('No supercells found in path!') 159 # Check if the supercells contains '&CONTROL' and abort if so 160 supercell_sample = supercells[0] 161 is_control = find.lines(supercell_sample, r'(&CONTROL|&control)', 1, 0, False, True) 162 if is_control: 163 raise RuntimeError('Supercells already contain &CONTROL! Did you do this already?') 164 # Check if the keyword is in the scf file 165 is_header = find.lines(scf_file, r'ATOMIC_SPECIES', 1, 0, False, False) 166 if not is_header: 167 raise RuntimeError('No ATOMIC_SPECIES found in header!') 168 # Copy the scf to a temp file 169 scf_temp2 = '_temp_scf_with_updated_supercell_values.in' 170 shutil.copy(scf_file, scf_temp2) 171 values = pwx.read_in(scf_temp2) 172 # Find the new number of atoms and replace the line 173 updated_values = find.lines(supercell_sample, 'ibrav', 1) # ! ibrav = 0, nat = 384, ntyp = 5 174 if not updated_values: 175 print("!!! Okay listen, this is weird. This line of code should never be running, " 176 "but for some reson I couldn't find the updated values in the supercells. " 177 "Please, introduce the NEW NUMBER OF ATOMS in the supercells manually (int):") 178 nat = int(input('nat = ')) 179 else: 180 nat = int(extract.number(updated_values[0], 'nat')) 181 pwx.set_value(scf_temp2, 'nat', nat) 182 print(f'Updated nat: {values['nat']} -> {nat}') 183 # Remove the lattice parameters, since Phonopy already indicates units 184 pwx.set_value(scf_temp2, 'celldm(1)', '') 185 pwx.set_value(scf_temp2, 'A', '') 186 pwx.set_value(scf_temp2, 'B', '') 187 pwx.set_value(scf_temp2, 'C', '') 188 pwx.set_value(scf_temp2, 'cosAB', '') 189 pwx.set_value(scf_temp2, 'cosAC', '') 190 pwx.set_value(scf_temp2, 'cosBC', '') 191 print('Updated lattice parameters') 192 # Remove the top content from the temp file 193 edit.delete_under(scf_temp2, 'K_POINTS', -1, 2, False) 194 # Update extensive energy values 195 if update_E: 196 old_nat = values['nat'] 197 new_atoms_factor = nat / old_nat 198 etot_conv_thr = values['etot_conv_thr'] 199 conv_thr = values['conv_thr'] 200 new_etot_conv_thr = etot_conv_thr * new_atoms_factor 201 new_conv_thr = conv_thr * new_atoms_factor 202 pwx.set_value(scf_temp2, 'etot_conv_thr', new_etot_conv_thr) 203 pwx.set_value(scf_temp2, 'conv_thr', new_conv_thr) 204 print(f'Updated etot_conv_thr: {etot_conv_thr} -> {new_etot_conv_thr}') 205 print(f'Updated conv_thr: {conv_thr} -> {new_conv_thr}') 206 # Update any other user-defined values 207 if update: 208 pwx.set_values(scf_temp2, update) 209 for key, value in update.items(): 210 print(f'Updated {key}: {values[key]} -> {value}') 211 # Add the header to the supercells 212 print(f'\nAdding header to the supercells...') 213 with open(scf_temp2, 'r') as f: 214 header = f.read() 215 for supercell in supercells: 216 edit.insert_at(supercell, header, 0) 217 # Remove the temp file 218 os.remove(scf_temp2) 219 print('Done.') 220 return None
44def make_supercells( 45 relax_in:str='relax.in', 46 relax_out:str='relax.out', 47 scf:str=None, 48 slurm_template:str='template.slurm', 49 folder:str=None, 50 dimension:str='2 2 2', 51 amplitude:float=None, 52 update:dict=None, 53 update_E:bool=True, 54 ) -> None: 55 """ 56 Creates and prepares the supercell inputs of Phonopy, 57 58 These supercells are created from the `relax_in` and `relax_out` files in the `folder` 59 ('relax.in', 'relax.out' and CWD by default, respectively), 60 needed for the Phonopy calculations with Quantum ESPRESSO. 61 Alternatively, a previously relaxed `scf` input file can be provided, 62 which will override the creation of a new scf file 63 from the `relax_in` and `relax_out` files. 64 The cells have a given `dimension` ('2 2 2' by default), 65 and the displacement `amplitude` is set to phonopy's default unless specified. 66 67 Extensive convergence values for the energy (`etot_conv_thr` and `conv_thr`) 68 are updated automatically according to the supercell size. 69 This can be disabled with `update_E=False`. 70 Any input value can be updated with an `update` dict, 71 overriding automatic values. 72 73 By default, at the end of the execution it will check 74 that an `slurm_template` ('template.slurm') is present and valid; 75 this is, containing the keywords `JOBNAME`, `INPUT` and `OUTPUT`. 76 If not, an example with instructions will be provided. 77 This check can be skipped with `slurm_template=''`. 78 The template will allow to easily run the Phonopy calculations with the one-line command 79 `aton.api.slurm.sbatch('supercell-', 'template.slurm')`. 80 """ 81 print(f'\nWelcome to aton.api.phonopy {__version__}\n' 82 'Creating all supercell inputs with Phonopy for Quantum ESPRESSO...\n') 83 if not scf: 84 pwx.scf_from_relax(folder, relax_in, relax_out, update=update) 85 scf = 'scf.in' 86 _check_dims = extract.coords(dimension) 87 if len(_check_dims) != 3: 88 raise ValueError('Supercell dimension must be given as "nx ny nz"!') 89 _supercells_from_scf(folder, scf, dimension, amplitude) 90 _copy_scf_header_to_supercells(folder, scf, update, update_E) 91 print('\n------------------------------------------------------\n' 92 'PLEASE CHECH BELOW THE CONTENT OF supercell-001.in\n' 93 '------------------------------------------------------\n') 94 call.bash('head -n 100 supercell-001.in') 95 print('\n------------------------------------------------------\n' 96 'PLEASE CHECH THE CONTENT OF supercell-001.in\n' 97 'The first 100 lines of the input were printed above!\n' 98 '------------------------------------------------------\n\n' 99 'If it seems correct, run the calculations with:\n' 100 f"aton.api.slurm.sbatch('supercell-', '{slurm_template}')\n") 101 if slurm_template: 102 slurm.check_template(slurm_template, folder) 103 return None
Creates and prepares the supercell inputs of Phonopy,
These supercells are created from the relax_in and relax_out files in the folder
('relax.in', 'relax.out' and CWD by default, respectively),
needed for the Phonopy calculations with Quantum ESPRESSO.
Alternatively, a previously relaxed scf input file can be provided,
which will override the creation of a new scf file
from the relax_in and relax_out files.
The cells have a given dimension ('2 2 2' by default),
and the displacement amplitude is set to phonopy's default unless specified.
Extensive convergence values for the energy (etot_conv_thr and conv_thr)
are updated automatically according to the supercell size.
This can be disabled with update_E=False.
Any input value can be updated with an update dict,
overriding automatic values.
By default, at the end of the execution it will check
that an slurm_template ('template.slurm') is present and valid;
this is, containing the keywords JOBNAME, INPUT and OUTPUT.
If not, an example with instructions will be provided.
This check can be skipped with slurm_template=''.
The template will allow to easily run the Phonopy calculations with the one-line command
aton.api.slurm.sbatch('supercell-', 'template.slurm').