diff --git a/doc/changelog.md b/doc/changelog.md index 480a9b91..6f6212fe 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,14 @@ # Change Log +## Jul-22-2024: Version 3.3.3 + +- Provide functionality by `--cf3` and `--cf2` command options to create force + constants from displacement-force dataset of random displacements when + an external force constants calculator is specified. +- New command line options `--rd`, `--rd-fc2`, `--fc-calc`, `--fc-calc-opt` and + `--sp` to support random displacements. + ## Jul-22-2024: Version 3.3.2 - Minor fix of `phono3py.load` function for reading displacements from diff --git a/doc/command-options.md b/doc/command-options.md index e48a393a..8979cc06 100644 --- a/doc/command-options.md +++ b/doc/command-options.md @@ -174,6 +174,8 @@ created from `FORCES_FC2` and `phono3py_disp.yaml` instead of `FORCES_FC3` and % phono3py --cfs --dim-fc2="x x x" ``` +(sp_option)= + ### `--sp` or `--save-params` Instead of `FORCES_FC3`, `phono3py_params.yaml` is generated. This option must @@ -296,7 +298,7 @@ very accurate. The default value depends on calculator. See {ref}`default_displacement_distance_for_calculator`. -(fc_calculator_options_option)= +(fc_calculator_option)= ### `--fc-calc`, `--fc-calculator` (`FC_CALCULATOR`) Choice of force constants calculator. @@ -313,6 +315,7 @@ Those for fc2 and fc3 are seprated by `|` such as `symfc|` . Blank means to employ the finite difference method for systematic displacements generated by the option `-d`. +(fc_calculator_options_option)= ### `--fc-calc-opt`, `--fc-calculator-options` (`FC_CALCULATOR_OPTIONS`) Special options for force constants calculators. diff --git a/doc/conf.py b/doc/conf.py index bf1a79a5..da5cb499 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -60,7 +60,7 @@ # The short X.Y version. version = "3.3" # The full version, including alpha/beta/rc tags. -release = "3.3.2" +release = "3.3.3" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/cutoff-pair.md b/doc/cutoff-pair.md index 03228c21..a07b1332 100644 --- a/doc/cutoff-pair.md +++ b/doc/cutoff-pair.md @@ -2,7 +2,11 @@ # Force constants calculation with cutoff pair-distance -Here the detail of the command option {ref}`--cutoff_pair ` +Since this calculation is a little bit tricky. It may be recommended to try +{ref}`random-displacements` with `--fc-calc-opt "cutoff = VAL"` before trying +this option. + +Here the detail of the command option {ref}`--cutoff-pair ` is explained. diff --git a/doc/random-displacements.md b/doc/random-displacements.md index 89b746b9..4c4b1185 100644 --- a/doc/random-displacements.md +++ b/doc/random-displacements.md @@ -1,5 +1,5 @@ (random-displacements)= -# Randan displacements +# Force constants calculation with randan displacements of atoms Random displacements and corresponding forces in supercells can be employed as a displacement-force dataset for computing force constants. This requires an @@ -34,3 +34,92 @@ If random directional displacements for fc2 are expected, `--rd-fc2` and ``` where `--dim` is necessary but `--rd` is not. + +## Create `FORCES_FC3` and `FORCES_FC2` + +`FORCES_FC3` and optionally `FORCES_FC2`, which contains forces corresponding to +displacements, can be created by + +```bash +% phono3py --cf3 vasprun_xmls/vasprun-00{001..100}.xml +``` + +Here it is assumed that the forces were calculated by VASP, and the output files +(`vasprun.xml`) are stored in `vasprun_xmls` directory after renaming. When +running this command, `phono3py_disp.yaml` is automatically read. For the +different file name, e.g. `phono3py_disp_rd.yaml`, it is specified with `-c` +option: + +```bash +% phono3py -c phono3py_disp_rd.yaml --cf3 vasprun_xmls/vasprun-00{001..100}.xml +``` + +`FORCES_FC2` is created similarly, e.g., from the VASP output stored as +`vasprun_xmls/vasprun-ph000{1,2}.xml`, + +```bash +% phono3py --cf2 vasprun_xmls/vasprun-ph000{1,2}.xml +``` + +## Create `phono3py_params.yaml` + +Instead of creating `FORCES_FC3` and `FORCES_FC2`, more convenient data file to +store displacement-force dataset is created by `--sp` option: + +```bash +% phono3py --cf3 vasprun_xmls/vasprun-00{001..100}.xml --cf2 vasprun_xmls/vasprun-ph0000{1,2}.xml --sp +``` + +The advantage to employ `phono3py_params.yaml` is that this file can contain all +the information required to run phono3py such as crystal structure, supercell +information, displacements, forces, and parameters for non-analytical term +correction. This file is immediately usable for `phono3py-load` command ({ref}`phono3py_load_command`). + +## Calculation of force constants + +If `phono3py_disp.yaml` is located in current directory, force constants are +calculated from `FORCES_FC3` (and optionally `FORCES_FC2`) and +`phono3py_disp.yaml` by + +```bash +% phono3py --symfc -v +``` + +or with `phono3py_params.yaml` + +```bash +% phono3py -c phono3py_params.yaml --symfc -v +``` + +Similarly, it is performed by also using `phono3py-load` command, + +```bash +% phono3py-load --symfc -v +``` + +or + +```bash +% phono3py-load phono3py_params.yaml --symfc -v +``` + +## Cutoff pair-distance for fc3 calculation + +The number of supercells required for calculating fc3 depends on crystal +structure, crystal symmetry, and supercell size. For larger supercells, the +number can be very large. In addition, the required computational time and +memory space can also become large. In such case, it may be good to consider +introducing cutoff distance for pairs of atoms. It is performed by +`--fc-calc-opt` option as + +```bash +% phono3py --symfc -v --fc-calc-opt "cutoff=8" +``` + +The shortcut of `--fc-calc-opt "cutoff=8"` is `--cutoff-pair 8`. + +The convergence of fc3 has to be checked. With the same input of +displacement-force dataset, calculated force constants gradually converge by +increasing cutoff pair-distance. The convergence may be checked by lattice +thermal conductivity, but it may depend on quantity that is expected to be +calculated. diff --git a/phono3py/cui/create_force_constants.py b/phono3py/cui/create_force_constants.py index fbe9a5e3..740455f0 100644 --- a/phono3py/cui/create_force_constants.py +++ b/phono3py/cui/create_force_constants.py @@ -168,14 +168,9 @@ def create_phono3py_force_constants( if settings.read_fc2: _read_phono3py_fc2(phono3py, symmetrize_fc2, input_filename, log_level) else: - if phono3py.phonon_supercell_matrix is None: - force_filename = "FORCES_FC3" - else: - force_filename = "FORCES_FC2" _create_phono3py_fc2( phono3py, ph3py_yaml, - force_filename, symmetrize_fc2, settings.is_compact_fc, fc_calculator, @@ -219,20 +214,22 @@ def parse_forces( """ filename_read_from: Optional[str] = None - + dataset = None calculator = phono3py.calculator + # Get dataset from ph3py_yaml. dataset can be None. # physical_units can be overwritten if calculator is found in ph3py_yaml. - dataset = _extract_dataset_from_ph3py_yaml(ph3py_yaml, fc_type) + if ph3py_yaml: + dataset = _extract_dataset_from_ph3py_yaml(ph3py_yaml, fc_type) if dataset and ph3py_yaml.calculator: calculator = ph3py_yaml.calculator physical_units = get_default_physical_units(calculator) - if fc_type == "phonon_fc2": - natom = len(phono3py.phonon_supercell) - else: + if phono3py.phonon_supercell is None or fc_type == "fc3": natom = len(phono3py.supercell) + else: + natom = len(phono3py.phonon_supercell) if dataset: filename_read_from = phono3py_yaml_filename @@ -269,20 +266,18 @@ def parse_forces( assert dataset is not None if "natom" in dataset and dataset["natom"] != natom: - msg = ( + raise RuntimeError( "Number of atoms in supercell is not consistent with " - '"%s".' % filename_read_from + f'"{filename_read_from}".' ) - raise RuntimeError(msg) if log_level and filename_read_from is not None: print( - 'Displacement dataset for %s was read from "%s".' - % (fc_type, filename_read_from) + f'Displacement dataset for {fc_type} was read from "{filename_read_from}".' ) # Overwrite dataset['cutoff_distance'] when necessary. - if cutoff_pair_distance: + if fc_type == "fc3" and cutoff_pair_distance: if "cutoff_distance" not in dataset or ( "cutoff_distance" in dataset and cutoff_pair_distance < dataset["cutoff_distance"] @@ -295,10 +290,10 @@ def parse_forces( # dataset comes either from disp_fc*.yaml or phono3py*.yaml. if not forces_in_dataset(dataset): if force_filename is not None: - if fc_type == "phonon_fc2": - parse_FORCES_FC2(dataset, filename=force_filename) - else: + if fc_type == "fc3": parse_FORCES_FC3(dataset, filename=force_filename) + else: + parse_FORCES_FC2(dataset, filename=force_filename) if log_level: print( @@ -452,10 +447,8 @@ def read_type2_dataset(natom, filename="FORCES_FC3", log_level=0) -> Optional[di if len_first_line == 6: dataset = get_dataset_type2(f, natom) if log_level: - print( - "%d snapshots were found in %s." - % (len(dataset["displacements"]), "FORCES_FC3") - ) + n_disp = len(dataset["displacements"]) + print(f'{n_disp} snapshots were found in "{filename}".') else: dataset = None return dataset @@ -663,7 +656,6 @@ def run_pypolymlp_to_compute_phonon_forces( def _create_phono3py_fc2( phono3py: Phono3py, ph3py_yaml: Optional[Phono3pyYaml], - force_filename, symmetrize_fc2, is_compact_fc, fc_calculator, @@ -675,6 +667,11 @@ def _create_phono3py_fc2( force_filename is either "FORCES_FC2" or "FORCES_FC3". """ + if phono3py.phonon_supercell_matrix is None: + force_filename = "FORCES_FC3" + else: + force_filename = "FORCES_FC2" + _ph3py_yaml = _get_default_ph3py_yaml(ph3py_yaml) try: @@ -682,7 +679,7 @@ def _create_phono3py_fc2( phono3py, ph3py_yaml=_ph3py_yaml, force_filename=force_filename, - fc_type="fc2", + fc_type="phonon_fc2", log_level=log_level, ) except RuntimeError as e: @@ -752,12 +749,13 @@ def _to_ndarray(array, dtype="double"): return array -def _extract_dataset_from_ph3py_yaml(ph3py_yaml: Optional[Phono3pyYaml], fc_type): - dataset = None - if fc_type == "phonon_fc2": - if ph3py_yaml and ph3py_yaml.phonon_dataset is not None: - dataset = copy.deepcopy(ph3py_yaml.phonon_dataset) +def _extract_dataset_from_ph3py_yaml( + ph3py_yaml: Optional[Phono3pyYaml], fc_type +) -> Optional[dict]: + if ph3py_yaml.phonon_supercell is None or fc_type == "fc3": + if ph3py_yaml.dataset is not None: + return copy.deepcopy(ph3py_yaml.dataset) else: - if ph3py_yaml and ph3py_yaml.dataset is not None: - dataset = copy.deepcopy(ph3py_yaml.dataset) - return dataset + if ph3py_yaml.phonon_dataset is not None: + return copy.deepcopy(ph3py_yaml.phonon_dataset) + return None diff --git a/phono3py/cui/phono3py_script.py b/phono3py/cui/phono3py_script.py index 5ba25f55..0b0c6c2c 100644 --- a/phono3py/cui/phono3py_script.py +++ b/phono3py/cui/phono3py_script.py @@ -517,11 +517,13 @@ def grid_addresses_to_grid_points(grid_addresses, bz_grid): return bz_grid.grg2bzg[grid_points] -def create_supercells( +def create_supercells_with_displacements( settings: Phono3pySettings, cell_info: dict, confs_dict: dict, + unitcell_filename: str, interface_mode: Optional[str], + load_phono3py_yaml: bool, symprec: float, log_level: int, ): @@ -539,6 +541,16 @@ def create_supercells( log_level=log_level, ) + store_nac_params( + phono3py, + settings, + cell_info["phonopy_yaml"], + unitcell_filename, + log_level, + nac_factor=Hartree * Bohr, + load_phonopy_yaml=load_phono3py_yaml, + ) + if log_level: if phono3py.supercell.magnetic_moments is None: print("Spacegroup: %s" % phono3py.symmetry.get_international_table()) @@ -971,8 +983,15 @@ def main(**argparse_control): # Create supercells with displacements and then exit # ###################################################### if not settings.use_pypolymlp: - create_supercells( - settings, cell_info, confs_dict, interface_mode, symprec, log_level + create_supercells_with_displacements( + settings, + cell_info, + confs_dict, + unitcell_filename, + interface_mode, + load_phono3py_yaml, + symprec, + log_level, ) ####################### @@ -1091,15 +1110,16 @@ def main(**argparse_control): ################################## # Non-analytical term correction # ################################## - store_nac_params( - phono3py, - settings, - cell_info["phonopy_yaml"], - unitcell_filename, - log_level, - nac_factor=Hartree * Bohr, - load_phonopy_yaml=load_phono3py_yaml, - ) + if settings.is_nac: + store_nac_params( + phono3py, + settings, + cell_info["phonopy_yaml"], + unitcell_filename, + log_level, + nac_factor=Hartree * Bohr, + load_phonopy_yaml=load_phono3py_yaml, + ) ################### # Force constants # diff --git a/phono3py/version.py b/phono3py/version.py index a30ed251..00dbceca 100644 --- a/phono3py/version.py +++ b/phono3py/version.py @@ -34,4 +34,4 @@ # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -__version__ = "3.3.2" +__version__ = "3.3.3"