예제 #1
0
파일: calculator.py 프로젝트: obaica/qha
    def desired_pressure_status(self) -> None:
        d = self.settings

        if d['high_verbosity']:
            save_to_output(
                d['qha_output'],
                "The pressure range can be dealt with: [{0:6.2f} to {1:6.2f}] GPa"
                .format(self.p_tv_gpa[:, 0].max(), self.p_tv_gpa[:, -1].min()))

        if self.p_tv_gpa[:, -1].min() < self.desired_pressures_gpa.max():
            ntv_max = int(
                (self.p_tv_gpa[:, -1].min() - self.desired_pressures_gpa.min())
                / d['DELTA_P'])

            save_to_output(
                d['qha_output'],
                textwrap.dedent("""\
                           !!!ATTENTION!!!

                           DESIRED PRESSURE is too high (NTV is too large)!
                           QHA results might not be right!
                           Please reduce the NTV accordingly, for example, try to set NTV < {:4d}.
                           """.format(ntv_max)))

            raise ValueError(
                "DESIRED PRESSURE is too high (NTV is too large), qha results might not be right!"
            )
예제 #2
0
파일: calculator.py 프로젝트: obaica/qha
    def read_input(self):
        self._degeneracies = tuple(self.settings['input'].values())
        input_data_files = tuple(self.settings['input'].keys())

        formula_unit_numbers = []
        volumes = []
        static_energies = []
        frequencies = []
        q_weights = []

        for inp in input_data_files:
            nm_tmp, volumes_tmp, static_energies_tmp, freq_tmp, weights_tmp = read_input(
                inp)

            if not qha.tools.is_monotonic_decreasing(volumes_tmp):
                # TODO: Clean this sentence
                save_to_output(
                    self.settings['qha_output'],
                    "Check the input file to make sure the volume decreases")
                raise ValueError(
                    "Check the input file to make sure the volumes are monotonic decreasing!"
                )

            formula_unit_numbers.append(nm_tmp)
            volumes.append(volumes_tmp)
            static_energies.append(static_energies_tmp)
            frequencies.append(freq_tmp)
            q_weights.append(weights_tmp)

        formula_unit_numbers = np.array(formula_unit_numbers)
        volumes = np.array(volumes)
        static_energies = np.array(static_energies)
        frequencies = np.array(frequencies)
        q_weights = np.array(q_weights)

        if not len(set(formula_unit_numbers)) == 1:
            raise RuntimeError(
                "All the formula unit number in all inputs should be the same!"
            )

        if len(volumes.shape) == 1:
            raise RuntimeError(
                "All configurations should have same number of volumes!")

        # Choose any of them since they are all the same
        self._formula_unit_number = formula_unit_numbers[0]
        self._volumes = volumes
        self._static_energies = static_energies
        self._frequencies = frequencies
        self._q_weights = q_weights
예제 #3
0
    def run(self, namespace):
        start_time_total = time.time()

        user_settings = {}
        file_settings = namespace.settings
        settings = from_yaml(file_settings)

        for key in ('input', 'calculation', 'thermodynamic_properties',
                    'static_only', 'energy_unit', 'T_MIN', 'NT', 'DT',
                    'DT_SAMPLE', 'P_MIN', 'NTV', 'DELTA_P', 'DELTA_P_SAMPLE',
                    'volume_ratio', 'order', 'p_min_modifier', 'T4FV',
                    'output_directory', 'high_verbosity'):
            try:
                user_settings.update({key: settings[key]})
            except KeyError:
                continue

        if not os.path.exists(user_settings['output_directory']):
            os.makedirs(user_settings['output_directory'])

        user_settings.update({
            'qha_output':
            os.path.join(user_settings['output_directory'], 'output.txt')
        })

        try:
            os.remove(user_settings['qha_output'])
        except OSError:
            pass

        save_to_output(user_settings['qha_output'], make_starting_string())

        calculation_type = user_settings['calculation'].lower()
        if calculation_type == 'single':
            calc = Calculator(user_settings)
            print("You have single-configuration calculation assumed.")
        elif calculation_type == 'same phonon dos':
            calc = SamePhDOSCalculator(user_settings)
            print(
                "You have multi-configuration calculation with the same phonon DOS assumed."
            )
        elif calculation_type == 'different phonon dos':
            calc = DifferentPhDOSCalculator(user_settings)
            print(
                "You have multi-configuration calculation with different phonon DOS assumed."
            )
        else:
            raise ValueError(
                "The 'calculation' in your settings in not recognized! It must be one of:"
                "'single', 'same phonon dos', 'different phonon dos'!")

        save_to_output(
            user_settings['qha_output'],
            make_tp_info(calc.temperature_array[0],
                         calc.temperature_array[-1 - 4],
                         calc.desired_pressures_gpa[0],
                         calc.desired_pressures_gpa[-1]))

        calc.read_input()

        print(
            "Caution: If negative frequencies found, they are currently treated as 0!"
        )
        tmp = calc.where_negative_frequencies
        # Don't delete this parenthesis!
        if tmp is not None and not (tmp.T[-1].max() <= 2):
            if calc.frequencies.ndim == 4:  # Multiple configuration
                for indices in tmp:
                    print(
                        "Found negative frequency in {0}th configuration {1}th volume {2}th q-point {3}th band"
                        .format(*tuple(indices + 1)))
            elif calc.frequencies.ndim == 3:  # Single configuration
                for indices in tmp:
                    print(
                        "Found negative frequency in {0}th volume {1}th q-point {2}th band"
                        .format(*tuple(indices + 1)))

        calc.refine_grid()

        if user_settings['high_verbosity']:
            save_to_output(
                user_settings['qha_output'],
                'The volume range used in this calculation expanded x {0:6.4f}'
                .format(calc.v_ratio))

        calc.desired_pressure_status()

        temperature_array = calc.temperature_array
        desired_pressures_gpa = calc.desired_pressures_gpa
        temperature_sample = calc.temperature_sample_array
        p_sample_gpa = calc.pressure_sample_array

        results_folder = pathlib.Path(user_settings['output_directory'])

        calculation_option = {
            'F': 'f_tp',
            'G': 'g_tp',
            'H': 'h_tp',
            'U': 'u_tp',
            'V': 'v_tp',
            'Cv': 'cv_tp_jmolk',
            'Cp': 'cp_tp_jmolk',
            'Bt': 'bt_tp_gpa',
            'Btp': 'btp_tp',
            'Bs': 'bs_tp_gpa',
            'alpha': 'alpha_tp',
            'gamma': 'gamma_tp',
        }

        file_ftv_fitted = results_folder / 'f_tv_fitted_ev_ang3.txt'
        save_x_tv(calc.f_tv_ev, temperature_array, calc.finer_volumes_ang3,
                  temperature_sample, file_ftv_fitted)

        file_ftv_non_fitted = results_folder / 'f_tv_nonfitted_ev_ang3.txt'
        save_x_tv(calc.vib_ev, temperature_array, calc.volumes_ang3,
                  temperature_sample, file_ftv_non_fitted)

        file_ptv_gpa = results_folder / 'p_tv_gpa.txt'
        save_x_tv(calc.p_tv_gpa, temperature_array, calc.finer_volumes_ang3,
                  temperature_sample, file_ptv_gpa)

        file_stv_j = results_folder / 's_tv_j.txt'
        save_x_tv(calc.s_tv_j, temperature_array, calc.finer_volumes_ang3,
                  temperature_sample, file_stv_j)

        for idx in calc.settings['thermodynamic_properties']:
            if idx in ['F', 'G', 'H', 'U']:
                attr_name = calculation_option[idx] + \
                    '_' + calc.settings['energy_unit']
                file_name = attr_name + '.txt'
                file_dir = results_folder / file_name
                save_x_tp(getattr(calc, attr_name), temperature_array,
                          desired_pressures_gpa, p_sample_gpa, file_dir)

            if idx == 'V':
                v_bohr3 = calculation_option[idx] + '_' + 'bohr3'
                file_name_bohr3 = v_bohr3 + '.txt'
                file_dir_au = results_folder / file_name_bohr3
                v_ang3 = calculation_option[idx] + '_' + 'ang3'
                file_name_ang3 = v_ang3 + '.txt'
                file_dir_ang3 = results_folder / file_name_ang3

                save_x_tp(getattr(calc, v_bohr3), temperature_array,
                          desired_pressures_gpa, p_sample_gpa, file_dir_au)
                save_x_tp(getattr(calc, v_ang3), temperature_array,
                          desired_pressures_gpa, p_sample_gpa, file_dir_ang3)

            if idx in ['Cv', 'Cp', 'Bt', 'Btp', 'Bs', 'alpha', 'gamma']:
                attr_name = calculation_option[idx]
                file_name = attr_name + '.txt'
                file_dir = results_folder / file_name
                save_x_tp(getattr(calc, attr_name), temperature_array,
                          desired_pressures_gpa, p_sample_gpa, file_dir)

        end_time_total = time.time()
        time_elapsed = end_time_total - start_time_total
        save_to_output(user_settings['qha_output'],
                       make_ending_string(time_elapsed))