diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c2d43d64..57a90a37 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - "--ignore=E203,W503" - repo: https://github.com/psf/black - rev: 23.11.0 + rev: 23.10.1 hooks: - id: black args: diff --git a/example/Si-QE/disp_fc3.yaml b/example/Si-QE/disp_fc3.yaml deleted file mode 100644 index 21814c41..00000000 --- a/example/Si-QE/disp_fc3.yaml +++ /dev/null @@ -1,330 +0,0 @@ -natom: 64 -num_first_displacements: 1 -num_second_displacements: 110 -num_displacements_created: 111 -first_atoms: -- number: 1 - displacement: - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00001 - second_atoms: - - number: 1 - distance: 0.000000 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00002 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00003 - - number: 2 - distance: 10.329553 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00004 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00005 - - number: 3 - distance: 10.329553 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00006 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00007 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00008 - - number: 4 - distance: 14.608194 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00009 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00010 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00011 - - number: 7 - distance: 14.608194 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00012 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00013 - - number: 8 - distance: 17.891310 - displacements: - - [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00014 - - [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00015 - - number: 9 - distance: 7.304097 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00016 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00017 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00018 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00019 - - number: 10 - distance: 12.651067 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00020 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00021 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00022 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00023 - - number: 11 - distance: 7.304097 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00024 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00025 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00026 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00027 - - number: 12 - distance: 12.651067 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00028 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00029 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00030 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00031 - - number: 17 - distance: 7.304097 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00032 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00033 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00034 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00035 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00036 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00037 - - number: 18 - distance: 7.304097 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00038 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00039 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00040 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00041 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00042 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00043 - - number: 19 - distance: 12.651067 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00044 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00045 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00046 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00047 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00048 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00049 - - number: 20 - distance: 12.651067 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00050 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00051 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00052 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00053 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00054 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00055 - - number: 33 - distance: 13.418483 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00056 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00057 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00058 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00059 - - number: 34 - distance: 11.256369 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00060 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00061 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00062 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00063 - - number: 35 - distance: 11.256369 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00064 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00065 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00066 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00067 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00068 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00069 - - number: 36 - distance: 8.564813 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00070 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00071 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00072 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00073 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00074 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00075 - - number: 39 - distance: 8.564813 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00076 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00077 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00078 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00079 - - number: 40 - distance: 4.472828 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00080 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00081 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00082 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00083 - - number: 49 - distance: 8.564813 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00084 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00085 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00086 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00087 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00088 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00089 - - number: 50 - distance: 11.256369 - displacements: - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00090 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00091 - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00092 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00093 - - [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00094 - - [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00095 - - number: 51 - distance: 4.472828 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00096 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00097 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00098 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00099 - - number: 52 - distance: 8.564813 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00100 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00101 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00102 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00103 - - number: 53 - distance: 11.256369 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00104 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00105 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00106 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00107 - - number: 54 - distance: 13.418483 - displacements: - - [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00108 - - [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00109 - - [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00110 - - [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00111 -lattice: -- [ 20.659105641913271, 0.000000000000000, 0.000000000000000 ] -- [ 0.000000000000000, 20.659105641913271, 0.000000000000000 ] -- [ 0.000000000000000, 0.000000000000000, 20.659105641913271 ] -atoms: -- symbol: Si # 1 - position: [ 0.43750000000000, 0.43750000000000, 0.43750000000000 ] -- symbol: Si # 2 - position: [ 0.93750000000000, 0.43750000000000, 0.43750000000000 ] -- symbol: Si # 3 - position: [ 0.43750000000000, 0.93750000000000, 0.43750000000000 ] -- symbol: Si # 4 - position: [ 0.93750000000000, 0.93750000000000, 0.43750000000000 ] -- symbol: Si # 5 - position: [ 0.43750000000000, 0.43750000000000, 0.93750000000000 ] -- symbol: Si # 6 - position: [ 0.93750000000000, 0.43750000000000, 0.93750000000000 ] -- symbol: Si # 7 - position: [ 0.43750000000000, 0.93750000000000, 0.93750000000000 ] -- symbol: Si # 8 - position: [ 0.93750000000000, 0.93750000000000, 0.93750000000000 ] -- symbol: Si # 9 - position: [ 0.43750000000000, 0.18750000000000, 0.18750000000000 ] -- symbol: Si # 10 - position: [ 0.93750000000000, 0.18750000000000, 0.18750000000000 ] -- symbol: Si # 11 - position: [ 0.43750000000000, 0.68750000000000, 0.18750000000000 ] -- symbol: Si # 12 - position: [ 0.93750000000000, 0.68750000000000, 0.18750000000000 ] -- symbol: Si # 13 - position: [ 0.43750000000000, 0.18750000000000, 0.68750000000000 ] -- symbol: Si # 14 - position: [ 0.93750000000000, 0.18750000000000, 0.68750000000000 ] -- symbol: Si # 15 - position: [ 0.43750000000000, 0.68750000000000, 0.68750000000000 ] -- symbol: Si # 16 - position: [ 0.93750000000000, 0.68750000000000, 0.68750000000000 ] -- symbol: Si # 17 - position: [ 0.18750000000000, 0.43750000000000, 0.18750000000000 ] -- symbol: Si # 18 - position: [ 0.68750000000000, 0.43750000000000, 0.18750000000000 ] -- symbol: Si # 19 - position: [ 0.18750000000000, 0.93750000000000, 0.18750000000000 ] -- symbol: Si # 20 - position: [ 0.68750000000000, 0.93750000000000, 0.18750000000000 ] -- symbol: Si # 21 - position: [ 0.18750000000000, 0.43750000000000, 0.68750000000000 ] -- symbol: Si # 22 - position: [ 0.68750000000000, 0.43750000000000, 0.68750000000000 ] -- symbol: Si # 23 - position: [ 0.18750000000000, 0.93750000000000, 0.68750000000000 ] -- symbol: Si # 24 - position: [ 0.68750000000000, 0.93750000000000, 0.68750000000000 ] -- symbol: Si # 25 - position: [ 0.18750000000000, 0.18750000000000, 0.43750000000000 ] -- symbol: Si # 26 - position: [ 0.68750000000000, 0.18750000000000, 0.43750000000000 ] -- symbol: Si # 27 - position: [ 0.18750000000000, 0.68750000000000, 0.43750000000000 ] -- symbol: Si # 28 - position: [ 0.68750000000000, 0.68750000000000, 0.43750000000000 ] -- symbol: Si # 29 - position: [ 0.18750000000000, 0.18750000000000, 0.93750000000000 ] -- symbol: Si # 30 - position: [ 0.68750000000000, 0.18750000000000, 0.93750000000000 ] -- symbol: Si # 31 - position: [ 0.18750000000000, 0.68750000000000, 0.93750000000000 ] -- symbol: Si # 32 - position: [ 0.68750000000000, 0.68750000000000, 0.93750000000000 ] -- symbol: Si # 33 - position: [ 0.06250000000000, 0.06250000000000, 0.06250000000000 ] -- symbol: Si # 34 - position: [ 0.56250000000000, 0.06250000000000, 0.06250000000000 ] -- symbol: Si # 35 - position: [ 0.06250000000000, 0.56250000000000, 0.06250000000000 ] -- symbol: Si # 36 - position: [ 0.56250000000000, 0.56250000000000, 0.06250000000000 ] -- symbol: Si # 37 - position: [ 0.06250000000000, 0.06250000000000, 0.56250000000000 ] -- symbol: Si # 38 - position: [ 0.56250000000000, 0.06250000000000, 0.56250000000000 ] -- symbol: Si # 39 - position: [ 0.06250000000000, 0.56250000000000, 0.56250000000000 ] -- symbol: Si # 40 - position: [ 0.56250000000000, 0.56250000000000, 0.56250000000000 ] -- symbol: Si # 41 - position: [ 0.06250000000000, 0.31250000000000, 0.31250000000000 ] -- symbol: Si # 42 - position: [ 0.56250000000000, 0.31250000000000, 0.31250000000000 ] -- symbol: Si # 43 - position: [ 0.06250000000000, 0.81250000000000, 0.31250000000000 ] -- symbol: Si # 44 - position: [ 0.56250000000000, 0.81250000000000, 0.31250000000000 ] -- symbol: Si # 45 - position: [ 0.06250000000000, 0.31250000000000, 0.81250000000000 ] -- symbol: Si # 46 - position: [ 0.56250000000000, 0.31250000000000, 0.81250000000000 ] -- symbol: Si # 47 - position: [ 0.06250000000000, 0.81250000000000, 0.81250000000000 ] -- symbol: Si # 48 - position: [ 0.56250000000000, 0.81250000000000, 0.81250000000000 ] -- symbol: Si # 49 - position: [ 0.31250000000000, 0.06250000000000, 0.31250000000000 ] -- symbol: Si # 50 - position: [ 0.81250000000000, 0.06250000000000, 0.31250000000000 ] -- symbol: Si # 51 - position: [ 0.31250000000000, 0.56250000000000, 0.31250000000000 ] -- symbol: Si # 52 - position: [ 0.81250000000000, 0.56250000000000, 0.31250000000000 ] -- symbol: Si # 53 - position: [ 0.31250000000000, 0.06250000000000, 0.81250000000000 ] -- symbol: Si # 54 - position: [ 0.81250000000000, 0.06250000000000, 0.81250000000000 ] -- symbol: Si # 55 - position: [ 0.31250000000000, 0.56250000000000, 0.81250000000000 ] -- symbol: Si # 56 - position: [ 0.81250000000000, 0.56250000000000, 0.81250000000000 ] -- symbol: Si # 57 - position: [ 0.31250000000000, 0.31250000000000, 0.06250000000000 ] -- symbol: Si # 58 - position: [ 0.81250000000000, 0.31250000000000, 0.06250000000000 ] -- symbol: Si # 59 - position: [ 0.31250000000000, 0.81250000000000, 0.06250000000000 ] -- symbol: Si # 60 - position: [ 0.81250000000000, 0.81250000000000, 0.06250000000000 ] -- symbol: Si # 61 - position: [ 0.31250000000000, 0.31250000000000, 0.56250000000000 ] -- symbol: Si # 62 - position: [ 0.81250000000000, 0.31250000000000, 0.56250000000000 ] -- symbol: Si # 63 - position: [ 0.31250000000000, 0.81250000000000, 0.56250000000000 ] -- symbol: Si # 64 - position: [ 0.81250000000000, 0.81250000000000, 0.56250000000000 ] diff --git a/phono3py/api_phono3py.py b/phono3py/api_phono3py.py index feeb3631..210cadd3 100644 --- a/phono3py/api_phono3py.py +++ b/phono3py/api_phono3py.py @@ -34,6 +34,7 @@ # POSSIBILITY OF SUCH DAMAGE. import warnings +from typing import Optional import numpy as np from phonopy.exception import ForceCalculatorRequiredError @@ -155,7 +156,7 @@ def __init__( store_dense_gp_map=True, store_dense_svecs=True, symprec=1e-5, - calculator=None, + calculator: Optional[str] = None, log_level=0, lapack_zheev_uplo=None, ): @@ -254,7 +255,7 @@ def __init__( self._store_dense_svecs = store_dense_svecs self._cutoff_frequency = cutoff_frequency - self._calculator = calculator + self._calculator: Optional[str] = calculator self._log_level = log_level # Create supercell and primitive cell @@ -399,7 +400,7 @@ def get_version(self): return self.version @property - def calculator(self): + def calculator(self) -> Optional[str]: """Return calculator interface name. str diff --git a/phono3py/cui/create_force_constants.py b/phono3py/cui/create_force_constants.py index 9ab81bd4..feb9873e 100644 --- a/phono3py/cui/create_force_constants.py +++ b/phono3py/cui/create_force_constants.py @@ -33,6 +33,7 @@ # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import copy import os import sys from typing import Optional @@ -78,7 +79,12 @@ def create_phono3py_force_constants( output_filename: Optional[str] = None, log_level=1, ): - """Read or calculate force constants.""" + """Read or calculate force constants. + + This function is for the 'phonopy' command only and not for the + 'phonopy-load' command. + + """ # Only for build-in fc calculator. # These are not applied to external fc calculators. symmetrize_fc3r = settings.is_symmetrize_fc3_r or settings.fc_symmetry @@ -205,19 +211,43 @@ def parse_forces( fc_type=None, log_level=0, ): - """Read displacements and forces.""" - filename_read_from = None + """Read displacements and forces. + + Physical units of displacements and forces are converted following the + calculator name. The calculator name may be given as the user input or found + in phono3py-yaml file. When dumping to phono3py-yaml file, it is assumed + that displacements and forces are written in the default units (A and eV/A) + without writing calculator name in it. + + """ + filename_read_from: Optional[str] = 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 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: natom = len(phono3py.supercell) - # Get dataset from ph3py_yaml. dataset can be None. - dataset = _extract_dataset_from_ph3py_yaml(ph3py_yaml, fc_type) if dataset: filename_read_from = phono3py_yaml_filename + # Units of displacements and forces are converted. If forces don't + # exist, the convesion will not be performed for forces. + if calculator is not None: + _convert_unit_in_dataset( + dataset, + distance_to_A=physical_units["distance_to_A"], + force_to_eVperA=physical_units["force_to_eVperA"], + ) + # Try to read FORCES_FC* if type-2 and return dataset. # None is returned unless type-2. # can emit FileNotFoundError. @@ -230,6 +260,15 @@ def parse_forces( filename_read_from = force_filename dataset = _dataset + # Units of displacements and forces are converted. + if calculator is not None: + _convert_unit_in_dataset( + dataset, + distance_to_A=physical_units["distance_to_A"], + force_to_eVperA=physical_units["force_to_eVperA"], + ) + + # No dataset is found. "disp_fc*.yaml" is read. But this is deprecated. if dataset is None: if disp_filename is None: msg = ( @@ -242,6 +281,20 @@ def parse_forces( dataset = _read_disp_fc_yaml(disp_filename, fc_type) filename_read_from = disp_filename + # No forces should exist. Therefore only unit of displacements is + # converted. + if calculator is None: + if log_level: + print( + f'Displacements are read from "{disp_filename}", but ' + " the unit has not converted." + ) + else: + _convert_unit_in_dataset( + dataset, + distance_to_A=physical_units["distance_to_A"], + ) + if "natom" in dataset and dataset["natom"] != natom: msg = ( "Number of atoms in supercell is not consistent with " @@ -273,12 +326,18 @@ def parse_forces( else: parse_FORCES_FC3(dataset, filename=force_filename) + # Unit of displacements is already converted. + # Therefore, only unit of forces is converted. + if calculator is not None: + _convert_unit_in_dataset( + dataset, + force_to_eVperA=physical_units["force_to_eVperA"], + ) + if log_level: print('Sets of supercell forces were read from "%s".' % force_filename) sys.stdout.flush() - _convert_unit_in_dataset(dataset, phono3py.calculator) - return dataset @@ -567,11 +626,16 @@ def _create_phono3py_phonon_fc2( ) -def _convert_unit_in_dataset(dataset, calculator): - physical_units = get_default_physical_units(calculator) - force_to_eVperA = physical_units["force_to_eVperA"] - distance_to_A = physical_units["distance_to_A"] +def _convert_unit_in_dataset( + dataset: dict, + distance_to_A: Optional[float] = None, + force_to_eVperA: Optional[float] = None, +) -> None: + """Convert physical units of displacements and forces in dataset. + + dataset is overwritten. + """ if "first_atoms" in dataset: for d1 in dataset["first_atoms"]: if distance_to_A is not None: @@ -608,8 +672,8 @@ 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 = ph3py_yaml.phonon_dataset + dataset = copy.deepcopy(ph3py_yaml.phonon_dataset) else: if ph3py_yaml and ph3py_yaml.dataset is not None: - dataset = ph3py_yaml.dataset + dataset = copy.deepcopy(ph3py_yaml.dataset) return dataset diff --git a/phono3py/cui/load.py b/phono3py/cui/load.py index cdc03187..2b26956c 100644 --- a/phono3py/cui/load.py +++ b/phono3py/cui/load.py @@ -84,25 +84,24 @@ def load( ) -> Phono3py: """Create Phono3py instance from parameters and/or input files. - "phono3py_yaml"-like file is parsed unless crystal structure information - is given by unitcell_filename, supercell_filename, unitcell - (PhonopyAtoms-like), or supercell (PhonopyAtoms-like). - Even when "phono3py_yaml"-like file is parse, parameters except for - crystal structure can be overwritten. + "phono3py_yaml"-like file is parsed unless crystal structure information is + given by unitcell_filename, supercell_filename, unitcell + (PhonopyAtoms-like), or supercell (PhonopyAtoms-like). Even when + "phono3py_yaml"-like file is parse, parameters except for crystal structure + can be overwritten. - 'fc3.hdf5' is read if found in current directory. - Unless 'fc3.hdf5' is found and if 'FORCES_FC3' and 'disp_fc3.yaml" are - found, these are read and fc3 and fc2 are produced. + 'fc3.hdf5' is read if found in current directory. Unless 'fc3.hdf5' is found + and if 'FORCES_FC3' and 'disp_fc3.yaml" are found, these are read and fc3 + and fc2 are produced. - if 'fc2.hdf5' is found, this is read. - Unless 'fc2.hdf5' is found and if 'FORCES_FC2' and 'disp_fc2.yaml" are - found, these are read and fc2 is produced. + if 'fc2.hdf5' is found, this is read. Unless 'fc2.hdf5' is found and if + 'FORCES_FC2' and 'disp_fc2.yaml" are found, these are read and fc2 is + produced. When force_sets_filename and force_constants_filename are not given, - 'FORCES_FC3' and 'FORCES_FC2' are looked for in the current directory - as the default behaviour. When 'FORCES_FC3' ('FORCES_FC2') is given in - the type-1 format, 'disp_fc3.yaml' ('disp_fc2.yaml') is also necessary - and read. + 'FORCES_FC3' and 'FORCES_FC2' are looked for in the current directory as the + default behaviour. When 'FORCES_FC3' ('FORCES_FC2') is given in the type-1 + format, 'disp_fc3.yaml' ('disp_fc2.yaml') is also necessary and read. Crystal structure ----------------- @@ -115,18 +114,16 @@ def load( Force sets or force constants ----------------------------- - Optional. Means to provide information to generate force constants - and their priority: + Optional. Means to provide information to generate force constants and their + priority: 1. fc3_filename (fc2_filename) - 2. forces_fc3_filename (forces_fc2_filename). Do not forget that - for type-1 format, disp_fc3.yaml (disp_fc2.yaml) has to be given, - too. + 2. forces_fc3_filename (forces_fc2_filename). Do not forget that for + type-1 format, disp_fc3.yaml (disp_fc2.yaml) has to be given, too. 3. 'fc3.hdf5' and 'fc2.hdf5' are searched in current directory. 4. 'FORCES_FC3' and 'FORCES_FC2' are searched in current directory. 'FORCES_FC2' is optional. For type-1 format, 'disp_fc3.yaml' and - optionally 'disp_fc2.yaml' are also searched in current - directory. When 'FORCES_FC2' is not found, 'FORCES_FC3' is used - to create fc2. + optionally 'disp_fc2.yaml' are also searched in current directory. + When 'FORCES_FC2' is not found, 'FORCES_FC3' is used to create fc2. Parameters for non-analytical term correctiion (NAC) ---------------------------------------------------- @@ -139,45 +136,40 @@ def load( Parameters ---------- phono3py_yaml : str, optional - Filename of "phono3py.yaml"-like file. If this is given, the data - in the file are parsed. Default is None. + Filename of "phono3py.yaml"-like file. If this is given, the data in the + file are parsed. Default is None. supercell_matrix : array_like, optional - Supercell matrix multiplied to input cell basis vectors. - shape=(3, ) or (3, 3), where the former is considered a diagonal - matrix. Default is the unit matrix. - dtype=int + Supercell matrix multiplied to input cell basis vectors. shape=(3, ) or + (3, 3), where the former is considered a diagonal matrix. Default is the + unit matrix. dtype=int primitive_matrix : array_like or str, optional - Primitive matrix multiplied to input cell basis vectors. Default is - the identity matrix. - When given as array_like, shape=(3, 3), dtype=float. - When 'F', 'I', 'A', 'C', or 'R' is given instead of a 3x3 matrix, - the primitive matrix defined at - https://spglib.github.io/spglib/definition.html - is used. - When 'auto' is given, the centring type ('F', 'I', 'A', 'C', 'R', or - primitive 'P') is automatically chosen. - Default is 'auto'. + Primitive matrix multiplied to input cell basis vectors. Default is the + identity matrix. When given as array_like, shape=(3, 3), dtype=float. + When 'F', 'I', 'A', 'C', or 'R' is given instead of a 3x3 matrix, the + primitive matrix defined at + https://spglib.github.io/spglib/definition.html is used. When 'auto' is + given, the centring type ('F', 'I', 'A', 'C', 'R', or primitive 'P') is + automatically chosen. Default is 'auto'. phonon_supercell_matrix : array_like, optional - Supercell matrix used for fc2. In phono3py, supercell matrix for fc3 - and fc2 can be different to support longer range interaction of fc2 - than that of fc3. Unless setting this, supercell_matrix is used. - This is only valide when unitcell or unitcell_filename is given. - Default is None. + Supercell matrix used for fc2. In phono3py, supercell matrix for fc3 and + fc2 can be different to support longer range interaction of fc2 than + that of fc3. Unless setting this, supercell_matrix is used. This is only + valide when unitcell or unitcell_filename is given. Default is None. is_nac : bool, optional - If True, look for 'BORN' file. If False, NAS is turned off. - Default is True. + If True, look for 'BORN' file. If False, NAS is turned off. Default is + True. calculator : str, optional. - Calculator used for computing forces. This is used to switch the set - of physical units. Default is None, which is equivalent to "vasp". + Calculator used for computing forces. This is used to switch the set of + physical units when parsing calculator input/output files. Default is + None, which is equivalent to "vasp". unitcell : PhonopyAtoms, optional Input unit cell. Default is None. supercell : PhonopyAtoms, optional - Input supercell. With given, default value of primitive_matrix is set - to 'auto' (can be overwitten). supercell_matrix is ignored. Default is + Input supercell. With given, default value of primitive_matrix is set to + 'auto' (can be overwitten). supercell_matrix is ignored. Default is None. nac_params : dict, optional - Parameters required for non-analytical term correction. Default is - None. + Parameters required for non-analytical term correction. Default is None. {'born': Born effective charges (array_like, shape=(primitive cell atoms, 3, 3), dtype=float), 'dielectric': Dielectric constant matrix @@ -192,15 +184,13 @@ def load( Filename corresponding to 'BORN', a file contains non-analytical term correction parameters. forces_fc3_filename : sequence or os.PathLike, optional - A two-elemental sequence of filenames corresponding to - ('FORCES_FC3', 'disp_fc3.yaml') in the type-1 format or a filename - (os.PathLike) corresponding to 'FORCES_FC3' in the type-2 format. - Default is None. + A two-elemental sequence of filenames corresponding to ('FORCES_FC3', + 'disp_fc3.yaml') in the type-1 format or a filename (os.PathLike) + corresponding to 'FORCES_FC3' in the type-2 format. Default is None. forces_fc2_filename : os.PathLike or sequence, optional - A two-elemental sequence of filenames corresponding to - ('FORCES_FC2', 'disp_fc2.yaml') in the type-1 format or a filename - (os.PathLike) corresponding to 'FORCES_FC2' in the type-2 format. - Default is None. + A two-elemental sequence of filenames corresponding to ('FORCES_FC2', + 'disp_fc2.yaml') in the type-1 format or a filename (os.PathLike) + corresponding to 'FORCES_FC2' in the type-2 format. Default is None. fc3_filename : os.PathLike, optional Filename of a file corresponding to 'fc3.hdf5', a file contains third-order force constants. Default is None. @@ -210,32 +200,31 @@ def load( fc_calculator : str, optional Force constants calculator. Currently only 'alm'. Default is None. fc_calculator_options : str, optional - Optional parameters that are passed to the external fc-calculator. - This is given as one text string. How to parse this depends on the - fc-calculator. For alm, each parameter is splitted by comma ',', - and each set of key and value pair is written in 'key = value'. + Optional parameters that are passed to the external fc-calculator. This + is given as one text string. How to parse this depends on the + fc-calculator. For alm, each parameter is splitted by comma ',', and + each set of key and value pair is written in 'key = value'. factor : float, optional - Phonon frequency unit conversion factor. Unless specified, default - unit conversion factor for each calculator is used. + Phonon frequency unit conversion factor. Unless specified, default unit + conversion factor for each calculator is used. produce_fc : bool, optional - Setting False, force constants are not calculated from displacements - and forces. Default is True. + Setting False, force constants are not calculated from displacements and + forces. Default is True. is_symmetry : bool, optional Setting False, crystal symmetry except for lattice translation is not considered. Default is True. symmetrize_fc : bool, optional - Setting False, force constants are not symmetrized when creating - force constants from displacements and forces. Default is True. + Setting False, force constants are not symmetrized when creating force + constants from displacements and forces. Default is True. is_mesh_symmetry : bool, optional - Setting False, reciprocal mesh symmetry is not considered. - Default is True. + Setting False, reciprocal mesh symmetry is not considered. Default is + True. is_compact_fc : bool, optional fc3 are created in the array whose shape is - True: (primitive, supercell, supecell, 3, 3, 3) - False: (supercell, supercell, supecell, 3, 3, 3) + True: (primitive, supercell, supecell, 3, 3, 3) False: (supercell, + supercell, supecell, 3, 3, 3) and for fc2 - True: (primitive, supecell, 3, 3) - False: (supercell, supecell, 3, 3) + True: (primitive, supecell, 3, 3) False: (supercell, supecell, 3, 3) where 'supercell' and 'primitive' indicate number of atoms in these cells. Default is False. use_grg : bool, optional @@ -243,9 +232,9 @@ def load( store_dense_gp_map : bool, optional, Deprecated Use new format of BZ grid system. Default is True. store_dense_svecs : bool, optional, Deprecated - Shortest vectors are stored in the dense array format. This is - expected to be always True. Setting False is for rough - compatibility with v1.x. Default is True. + Shortest vectors are stored in the dense array format. This is expected + to be always True. Setting False is for rough compatibility with v1.x. + Default is True. symprec : float, optional Tolerance used to find crystal symmetry. Default is 1e-5. log_level : int, optional @@ -257,7 +246,7 @@ def load( or supercell_filename is not None or unitcell is not None or unitcell_filename is not None - ): # noqa E129 + ): cell, smat, pmat = load_helper.get_cell_settings( supercell_matrix=supercell_matrix, primitive_matrix=primitive_matrix, diff --git a/phono3py/cui/phono3py_argparse.py b/phono3py/cui/phono3py_argparse.py index be55a1c1..e93e3ccf 100644 --- a/phono3py/cui/phono3py_argparse.py +++ b/phono3py/cui/phono3py_argparse.py @@ -490,7 +490,7 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False): "--nac-method", dest="nac_method", default=None, - help="Non-analytical term correction method: Wang (default) or Gonze", + help="Non-analytical term correction method: Gonze (default) or Wang", ) if fc_symmetry: parser.add_argument( diff --git a/phono3py/interface/phono3py_yaml.py b/phono3py/interface/phono3py_yaml.py index a7c94b37..f2ed69f8 100644 --- a/phono3py/interface/phono3py_yaml.py +++ b/phono3py/interface/phono3py_yaml.py @@ -59,9 +59,9 @@ class Phono3pyYamlData: """PhonopyYaml data structure.""" - configuration: dict - calculator: str - physical_units: dict + configuration: Optional[dict] = None + calculator: Optional[str] = None + physical_units: Optional[dict] = None unitcell: Optional[PhonopyAtoms] = None primitive: Optional[Primitive] = None supercell: Optional[Supercell] = None diff --git a/phono3py/phonon3/fc3.py b/phono3py/phonon3/fc3.py index 7a6e3c4f..6b23e6bf 100644 --- a/phono3py/phonon3/fc3.py +++ b/phono3py/phonon3/fc3.py @@ -459,12 +459,11 @@ def _solve_fc3( solver = "numpy.linalg.pinv" if verbose: - text = "Computing fc3[ %d, x, x ] using %s with " % (first_atom_num + 1, solver) + print(f"Computing fc3[ {first_atom_num + 1}, x, x ] using {solver}.") if len(displacements_first) > 1: - text += "displacements:" + print("Displacements (in Angstrom):") else: - text += "a displacement:" - print(text) + print("One displacement (in Angstrom):") for i, v in enumerate(displacements_first): print(" [%7.4f %7.4f %7.4f]" % tuple(v)) sys.stdout.flush() diff --git a/test/cui/phono3py_params-qe-Si222.yaml.xz b/test/cui/phono3py_params-qe-Si222.yaml.xz new file mode 100644 index 00000000..1cb521d4 Binary files /dev/null and b/test/cui/phono3py_params-qe-Si222.yaml.xz differ diff --git a/test/cui/test_phono3py_load_script.py b/test/cui/test_phono3py_load_script.py index 665b55d9..3540e274 100644 --- a/test/cui/test_phono3py_load_script.py +++ b/test/cui/test_phono3py_load_script.py @@ -5,8 +5,10 @@ import pathlib from collections.abc import Sequence from dataclasses import dataclass, fields -from typing import Optional +from typing import Optional, Union +import h5py +import numpy as np import pytest from phono3py.cui.phono3py_script import main @@ -19,7 +21,7 @@ class MockArgs: """Mock args of ArgumentParser.""" - filename: Sequence[os.PathLike] + filename: Optional[Sequence[os.PathLike]] = None conf_filename: Optional[os.PathLike] = None fc_calculator: Optional[str] = None force_sets_mode: bool = False @@ -28,11 +30,22 @@ class MockArgs: output_yaml_filename: Optional[os.PathLike] = None show_num_triplets: bool = False write_grid_points: bool = False + fc_symmetry: bool = True + cell_filename: Optional[str] = None + is_bterta: Optional[bool] = None + mesh_numbers: Optional[Sequence] = None + temperatures: Optional[Sequence] = None + input_filename = None + output_filename = None + input_output_filename = None def __iter__(self): """Make self iterable to support in.""" return (getattr(self, field.name) for field in fields(self)) + def __contains__(self, item): + return item in (field.name for field in fields(self)) + def test_phono3py_load(): """Test phono3py-load script.""" @@ -71,19 +84,70 @@ def test_phono3py_load_with_typeII_dataset(fc_calculator, exit_code): file_path.unlink() -def _get_phono3py_load_args(phono3py_yaml_filepath, fc_calculator=None): - # Mock of ArgumentParser.args. - mockargs = MockArgs( - filename=[phono3py_yaml_filepath], - fc_calculator=fc_calculator, - log_level=1, +@pytest.mark.parametrize("load_phono3py_yaml", [True, False]) +def test_phono3py_with_QE_calculator(load_phono3py_yaml): + """Test phono3py-load script with QE calculator.""" + argparse_control = _get_phono3py_load_args( + cwd / "phono3py_params-qe-Si222.yaml.xz", + load_phono3py_yaml=load_phono3py_yaml, + is_bterta=True, + temperatures=[ + "300", + ], + mesh_numbers=["11", "11", "11"], ) + with pytest.raises(SystemExit): + main(**argparse_control) + + with h5py.File(cwd_called / "kappa-m111111.hdf5", "r") as f: + np.testing.assert_almost_equal(f["kappa"][0, 0], 118.93, decimal=1) + + # Clean files created by phono3py/phono3py-load script. + for created_filename in ( + "phono3py.yaml", + "fc2.hdf5", + "fc3.hdf5", + "kappa-m111111.hdf5", + ): + file_path = pathlib.Path(cwd_called / created_filename) + if file_path.exists(): + file_path.unlink() + + +def _get_phono3py_load_args( + phono3py_yaml_filepath: Union[str, pathlib.Path], + fc_calculator: Optional[str] = None, + load_phono3py_yaml: bool = True, + is_bterta: bool = False, + temperatures: Optional[Sequence] = None, + mesh_numbers: Optional[Sequence] = None, +): + # Mock of ArgumentParser.args. + if load_phono3py_yaml: + mockargs = MockArgs( + filename=[phono3py_yaml_filepath], + fc_calculator=fc_calculator, + is_bterta=is_bterta, + temperatures=temperatures, + mesh_numbers=mesh_numbers, + log_level=1, + ) + else: + mockargs = MockArgs( + filename=[], + fc_calculator=fc_calculator, + log_level=1, + cell_filename=phono3py_yaml_filepath, + is_bterta=is_bterta, + temperatures=temperatures, + mesh_numbers=mesh_numbers, + ) # See phono3py-load script. argparse_control = { - "fc_symmetry": True, - "is_nac": True, - "load_phono3py_yaml": True, + "fc_symmetry": load_phono3py_yaml, + "is_nac": load_phono3py_yaml, + "load_phono3py_yaml": load_phono3py_yaml, "args": mockargs, } return argparse_control