示例#1
0
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None,
                 include_stress=False):
        """
        Evaluate energies, forces and stresses of structures with trained
        machinea learning potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
            include_stress (bool): Whether to include stress components.
        """
        test_structures, test_forces, test_stresses = check_structures_forces_stresses(
            test_structures, test_forces, test_stresses)
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)
        _, df_orig = convert_docs(predict_pool, include_stress=include_stress)
        _, df_predict = convert_docs(pool_from(test_structures),
                                     include_stress=include_stress)
        outputs = self.model.predict_objs(objs=test_structures)
        df_predict["y_orig"] = df_predict["n"] * outputs

        return df_orig, df_predict
示例#2
0
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None):
        """
        Evaluate energies, forces and stresses of structures with trained
        machinea learning potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
        """
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)
        _, df_orig = convert_docs(predict_pool)
        _, df_predict = convert_docs(pool_from(test_structures))
        outputs = self.model.predict_objs(objs=test_structures)
        df_predict['y_orig'] = df_predict['n'] * outputs

        return df_orig, df_predict
示例#3
0
    def train(self,
              train_structures,
              train_energies,
              train_forces,
              train_stresses=None,
              include_stress=False,
              **kwargs):
        """
        Training data with models.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each
                structure with m atoms in structures list. m can be varied with
                each single structure case.
            train_stresses (list): List of (6, ) virial stresses of each
                structure in structures list.
            include_stress (bool): Whether to include stress components.
        """
        train_structures, train_forces, train_stresses = check_structures_forces_stresses(
            train_structures, train_forces, train_stresses)
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)
        _, df = convert_docs(train_pool, include_stress=include_stress)
        ytrain = df["y_orig"] / df["n"]
        xtrain = self.model.describer.transform(train_structures)
        self.model.fit(features=xtrain, targets=ytrain, **kwargs)
示例#4
0
文件: _site.py 项目: kcbhamu/maml
    def transform_one(self, structure: Structure) -> pd.DataFrame:
        """
        Args:
            structure (Structure): Pymatgen Structure object.
        """
        if not which('quip'):
            raise RuntimeError("quip has not been found.\n",
                               "Please refer to https://github.com/libAtoms/QUIP for ",
                               "further detail.")

        atoms_filename = 'structure.xyz'

        exe_command = ['quip']
        exe_command.append('atoms_filename={}'.format(atoms_filename))

        descriptor_command = ['soap']
        descriptor_command.append("cutoff" + '=' + '{}'.format(self.cutoff))
        descriptor_command.append("l_max" + '=' + '{}'.format(self.l_max))
        descriptor_command.append("n_max" + '=' + '{}'.format(self.n_max))
        descriptor_command.append("atom_sigma" + '=' + '{}'.format(self.atom_sigma))

        atomic_numbers = [str(element.number) for element in sorted(np.unique(structure.species))]
        n_Z = len(atomic_numbers)
        n_species = len(atomic_numbers)
        Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        species_Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        descriptor_command.append("n_Z" + '=' + str(n_Z))
        descriptor_command.append("Z" + '=' + Z)
        descriptor_command.append("n_species" + '=' + str(n_species))
        descriptor_command.append("species_Z" + '=' + species_Z)

        exe_command.append("descriptor_str=" + "{" +
                           "{}".format(' '.join(descriptor_command)) + "}")

        with ScratchDir('.'):
            _ = self.operator.write_cfgs(filename=atoms_filename,
                                         cfg_pool=pool_from([structure]))
            descriptor_output = 'output'
            p = subprocess.Popen(exe_command, stdout=open(descriptor_output, 'w'))
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = 'quip/soap exited with return code %d' % rc
                msg = stdout.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [i for i, m in enumerate(msg)
                                  if m.startswith('ERROR')][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            with zopen(descriptor_output, 'rt') as f:
                lines = f.read()

            descriptor_pattern = re.compile('DESC(.*?)\n', re.S)
            descriptors = pd.DataFrame([np.array(c.split(), dtype=np.float)
                                        for c in descriptor_pattern.findall(lines)])

        return descriptors
示例#5
0
    def train(self,
              train_structures,
              train_energies,
              train_forces,
              train_stresses=None,
              **kwargs):
        """
        Training data with model.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each
                structure with m atoms in structures list. m can be varied with
                each single structure case.
            train_stresses (list): List of (6, ) virial stresses of each
                structure in structures list.
        """
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)
        _, df = convert_docs(train_pool)
        ytrain = df['y_orig'] / df['n']
        xtrain = self.model.describer.transform(train_structures)
        self.model.fit(features=xtrain, targets=ytrain, **kwargs)
示例#6
0
文件: _gap.py 项目: racheallee/maml
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None,
                 predict_energies=True,
                 predict_forces=True,
                 predict_stress=False):
        """
        Evaluate energies, forces and stresses of structures with trained
        interatomic potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
            predict_energies (bool): Whether to predict energies of configurations.
            predict_forces (bool): Whether to predict forces of configurations.
            predict_stress (bool): Whether to predict virial stress of
                configurations.
        """
        if not which('quip'):
            raise RuntimeError(
                "quip has not been found.\n",
                "Please refer to https://github.com/libAtoms/QUIP for ",
                "further detail.")
        xml_file = 'predict.xml'
        original_file = 'original.xyz'
        predict_file = 'predict.xyz'
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)

        with ScratchDir('.'):
            _ = self.write_param(xml_file)
            original_file = self.write_cfgs(original_file,
                                            cfg_pool=predict_pool)
            _, df_orig = self.read_cfgs(original_file)

            exe_command = ["quip"]
            exe_command.append("atoms_filename={}".format(original_file))
            exe_command.append("param_filename={}".format(xml_file))
            if predict_energies:
                exe_command.append("energy=T")
            if predict_forces:
                exe_command.append("forces=T")
            if predict_stress:
                exe_command.append("virial=T")

            p = subprocess.Popen(exe_command, stdout=open(predict_file, 'w'))
            p.communicate()[0]

            _, df_predict = self.read_cfgs(predict_file, predict=True)

        return df_orig, df_predict
示例#7
0
    def train(self,
              train_structures,
              train_energies,
              train_forces,
              train_stresses=None,
              default_sigma=[0.0005, 0.1, 0.05, 0.01],
              use_energies=True,
              use_forces=True,
              use_stress=False,
              **kwargs):
        """
        Training data with gaussian process regression.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each structure
                with m atoms in structures list. m can be varied with each
                single structure case.
            train_stresses (list): List of (6, ) virial stresses of each
                structure in structures list.
            default_sigma (list): Error criteria in energies, forces, stress
                and hessian. Should have 4 numbers.
            use_energies (bool): Whether to use dft total energies for training.
                Default to True.
            use_forces (bool): Whether to use dft atomic forces for training.
                Default to True.
            use_stress (bool): Whether to use dft virial stress for training.
                Default to False.

            kwargs:
                l_max (int): Parameter to configure GAP. The band limit of
                    spherical harmonics basis function. Default to 12.
                n_max (int): Parameter to configure GAP. The number of radial basis
                    function. Default to 10.
                atom_sigma (float): Parameter to configure GAP. The width of gaussian
                    atomic density. Default to 0.5.
                zeta (float): Present when covariance function type is do product.
                    Default to 4.
                cutoff (float): Parameter to configure GAP. The cutoff radius.
                    Default to 4.0.
                cutoff_transition_width (float): Parameter to configure GAP.
                    The transition width of cutoff radial. Default to 0.5.
                delta (float): Parameter to configure Sparsification.
                    The signal variance of noise. Default to 1.
                f0 (float): Parameter to configure Sparsification.
                    The signal mean of noise. Default to 0.0.
                n_sparse (int): Parameter to configure Sparsification.
                    Number of sparse points.
                covariance_type (str): Parameter to configure Sparsification.
                    The type of convariance function. Default to dot_product.
                sparse_method (str): Method to perform clustering in sparsification.
                    Default to 'cur_points'.

                sparse_jitter (float): Intrisic error of atomic/bond energy,
                    used to regularise the sparse covariance matrix.
                    Default to 1e-8.
                e0 (float): Atomic energy value to be subtracted from energies
                    before fitting. Default to 0.0.
                e0_offset (float): Offset of baseline. If zero, the offset is
                    the average atomic energy of the input data or the e0
                    specified manually. Default to 0.0.
        """
        if not which('gap_fit'):
            raise RuntimeError(
                "gap_fit has not been found.\n",
                "Please refer to https://github.com/libAtoms/QUIP for ",
                "further detail.")

        train_structures, train_forces, train_stresses = \
            check_structures_forces_stresses(train_structures, train_forces, train_stresses)

        gap_sorted_elements = []
        for struct in train_structures:
            for specie in struct.species:
                if str(specie) not in gap_sorted_elements:
                    gap_sorted_elements.append(str(specie))

        self.elements = sorted(gap_sorted_elements, key=lambda x: Element(x))

        atoms_filename = 'train.xyz'
        xml_filename = 'train.xml'
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)

        exe_command = ["gap_fit"]
        exe_command.append('at_file={}'.format(atoms_filename))
        gap_configure_params = [
            'l_max', 'n_max', 'atom_sigma', 'zeta', 'cutoff',
            'cutoff_transition_width', 'delta', 'f0', 'n_sparse',
            'covariance_type', 'sparse_method'
        ]
        preprocess_params = ['sparse_jitter', 'e0', 'e0_offset']
        if len(default_sigma) != 4:
            raise ValueError(
                "The default sigma is supposed to have 4 numbers.")

        gap_command = ['soap']
        for param_name in gap_configure_params:
            param = kwargs.get(param_name) if kwargs.get(param_name) \
                else soap_params.get(param_name)
            gap_command.append(param_name + '=' + '{}'.format(param))
        gap_command.append('add_species=T')
        exe_command.append("gap=" + "{" + "{}".format(' '.join(gap_command)) +
                           "}")

        for param_name in preprocess_params:
            param = kwargs.get(param_name) if kwargs.get(param_name) \
                else soap_params.get(param_name)
            exe_command.append(param_name + '=' + '{}'.format(param))

        default_sigma = [str(f) for f in default_sigma]
        exe_command.append("default_sigma={%s}" % (' '.join(default_sigma)))

        if use_energies:
            exe_command.append('energy_parameter_name=dft_energy')
        if use_forces:
            exe_command.append('force_parameter_name=dft_force')
        if use_stress:
            exe_command.append('virial_parameter_name=dft_virial')
        exe_command.append('gp_file={}'.format(xml_filename))

        with ScratchDir('.'):
            self.write_cfgs(filename=atoms_filename, cfg_pool=train_pool)

            p = subprocess.Popen(exe_command, stdout=subprocess.PIPE)
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = 'gap_fit exited with return code %d' % rc
                msg = stdout.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith('ERROR')
                    ][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            def get_xml(xml_file):
                tree = ET.parse(xml_file)
                root = tree.getroot()
                potential_label = root.tag
                element_param = {}
                for gpcoordinates in list(root.iter('gpCoordinates')):
                    gp_descriptor = list(gpcoordinates.iter('descriptor'))[0]
                    gp_descriptor_text = gp_descriptor.findtext('.')
                    Z_pattern = re.compile(' Z=(.*?) ', re.S)
                    element = str(
                        get_el_sp(int(
                            Z_pattern.findall(gp_descriptor_text)[0])))
                    param = np.loadtxt(gpcoordinates.get('sparseX_filename'))
                    element_param[element] = param.tolist()

                return tree, element_param, potential_label

            tree, element_param, potential_label = get_xml(xml_filename)
            self.param['xml'] = tree
            self.param['element_param'] = element_param
            self.param['potential_label'] = potential_label

        return rc
示例#8
0
文件: _mtp.py 项目: zhenming-xu/maml
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None,
                 **kwargs):
        """
        Evaluate energies, forces and stresses of structures with trained
        interatomic potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
            kwargs: Parameters of write_param method.
        """
        if not which('mlp'):
            raise RuntimeError(
                "mlp has not been found.\n",
                "Please refer to http://gitlab.skoltech.ru/shapeev/mlip ",
                "for further detail.")
        fitted_mtp = 'fitted.mtp'
        original_file = 'original.cfgs'
        predict_file = 'predict.cfgs'
        test_structures, test_forces, test_stresses = \
            check_structures_forces_stresses(test_structures, test_forces, test_stresses)
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)

        with ScratchDir('.'):
            self.write_param(fitted_mtp=fitted_mtp,
                             Abinitio=0,
                             Driver=1,
                             Write_cfgs=predict_file,
                             Database_filename=original_file,
                             **kwargs)
            original_file = self.write_cfg(original_file,
                                           cfg_pool=predict_pool)
            _, df_orig = self.read_cfgs(original_file)

            p = subprocess.Popen([
                'mlp', 'run', 'mlip.ini', '--filename={}'.format(original_file)
            ],
                                 stdout=subprocess.PIPE)
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = 'mlp exited with return code %d' % rc
                msg = stdout.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith('ERROR')
                    ][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)
            if not os.path.exists(predict_file):
                predict_file = '_'.join([predict_file, '0'])
            _, df_predict = self.read_cfgs(predict_file)
        return df_orig, df_predict
示例#9
0
文件: _mtp.py 项目: zhenming-xu/maml
    def train(self,
              train_structures,
              train_energies,
              train_forces,
              train_stresses=None,
              unfitted_mtp=None,
              max_dist=5,
              radial_basis_size=8,
              max_iter=500,
              energy_weight=1,
              force_weight=1e-2,
              stress_weight=0):
        """
        Training data with moment tensor method.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each structure
                with m atoms in structures list. m can be varied with each single
                structure case.
            train_stresses (list): List of (6, ) virial stresses of each structure
                in structures list.
            unfitted_mtp (str): Define the initial mtp file. Default to the mtp file
                stored in .params directory.
            max_dist (float): The actual radial cutoff.
            radial_basis_size (int): Relevant to number of radial basis function.
            max_iter (int): The number of maximum iteration.
            energy_weight (float): The weight of energy.
            force_weight (float): The weight of forces.
            stress_weight (float): The weight of stresses.
        """
        if not which('mlp'):
            raise RuntimeError(
                "mlp has not been found.\n",
                "Please refer to http://gitlab.skoltech.ru/shapeev/mlip ",
                "for further detail.")
        train_structures, train_forces, train_stresses = \
            check_structures_forces_stresses(train_structures, train_forces, train_stresses)
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)
        elements = sorted(
            set(
                itertools.chain(
                    *[struct.species for struct in train_structures])))
        self.elements = [str(element) for element in elements]

        atoms_filename = 'train.cfgs'

        with ScratchDir('.'):
            atoms_filename = self.write_cfg(filename=atoms_filename,
                                            cfg_pool=train_pool)

            if not unfitted_mtp:
                raise RuntimeError("No specific parameter file provided.")
            MTP_file_path = os.path.join(module_dir, 'params', unfitted_mtp)
            shutil.copyfile(MTP_file_path,
                            os.path.join(os.getcwd(), unfitted_mtp))

            with open('min_dist', 'w') as f:
                p = subprocess.Popen(['mlp', 'mindist', atoms_filename],
                                     stdout=f)
            stdout = p.communicate()[0]

            with open('min_dist') as f:
                lines = f.readlines()
            min_dist = float(lines[-1].split(':')[1])

            with open(unfitted_mtp) as f:
                template = f.read()

            s = template % (len(
                self.elements), min_dist, max_dist, radial_basis_size)
            with open(unfitted_mtp, 'w') as f:
                f.write(s)

            save_fitted_mtp = '.'.join([
                unfitted_mtp.split('.')[0] + '_fitted',
                unfitted_mtp.split('.')[1]
            ])

            p = subprocess.Popen([
                'mlp', 'train', unfitted_mtp, atoms_filename,
                '--max-iter={}'.format(max_iter),
                '--trained-pot-name={}'.format(save_fitted_mtp),
                '--curr-pot-name={}'.format(unfitted_mtp),
                '--energy-weight={}'.format(energy_weight),
                '--force-weight={}'.format(force_weight),
                '--stress-weight={}'.format(stress_weight),
                '--init-params=same', '--auto-min-dist'
            ],
                                 stdout=subprocess.PIPE)
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = 'MLP exited with return code %d' % rc
                msg = stdout.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith('ERROR')
                    ][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            def load_config(filename):
                param = OrderedDict()
                with open(filename, 'r') as f:
                    lines = f.readlines()
                param['safe'] = [line.rstrip() for line in lines[:-2]]
                for line in lines[-2:]:
                    key = line.rstrip().split(' = ')[0]
                    value = json.loads(line.rstrip().split(' = ')[1].replace(
                        '{', '[').replace('}', ']'))
                    param[key] = value
                return param

            self.param = load_config(save_fitted_mtp)
        return rc
示例#10
0
文件: _nnp.py 项目: zhenming-xu/maml
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None):
        """
        Evaluate energies, forces and stresses of structures with trained
        interatomic potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
        """
        if not which('nnp-predict'):
            raise RuntimeError("NNP Predictor has not been found.")

        original_file = 'input.data'
        predict_file = 'output.data'
        test_structures, test_forces, test_stresses = \
            check_structures_forces_stresses(test_structures, test_forces, test_stresses)
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)
        with ScratchDir('.'):
            _, _ = self.write_param()
            original_file = self.write_cfgs(original_file,
                                            cfg_pool=predict_pool)
            _, df_orig = self.read_cfgs(original_file)

            input_filename = self.write_input()

            dfs = []
            for data in predict_pool:
                _ = self.write_cfgs(original_file, cfg_pool=[data])
                p_evaluation = subprocess.Popen(
                    ['nnp-predict', input_filename],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE)
                stdout, stderr = p_evaluation.communicate()

                rc = p_evaluation.returncode
                if rc != 0:
                    error_msg = 'n2p2 exited with return code %d' % rc
                    msg = stderr.decode("utf-8").split('\n')[:-1]
                    try:
                        error_line = [
                            i for i, m in enumerate(msg)
                            if m.startswith('ERROR')
                        ][0]
                        error_msg += ', '.join(msg[error_line:])
                    except Exception:
                        error_msg += ', '
                        error_msg += msg[-1]
                    raise RuntimeError(error_msg)

                _, df = self.read_cfgs(predict_file)
                dfs.append(df)
            df_predict = pd.concat(dfs, ignore_index=True)

        return df_orig, df_predict
示例#11
0
文件: _nnp.py 项目: zhenming-xu/maml
    def train(self,
              train_structures,
              train_energies,
              train_forces,
              train_stresses=None,
              **kwargs):
        """
        Training data with moment tensor method.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each structure
                with m atoms in structures list. m can be varied with each
                single structure case.
            train_stresses (list): List of (6, ) virial stresses of each
                structure in structures list.
            kwargs: Parameters in write_input method.
        """
        if not which('nnp-train'):
            raise RuntimeError("NNP Trainer has not been found.")
        train_structures, train_forces, train_stresses = \
            check_structures_forces_stresses(train_structures, train_forces, train_stresses)
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)
        atoms_filename = 'input.data'

        with ScratchDir('.'):
            _ = self.write_cfgs(filename=atoms_filename, cfg_pool=train_pool)
            output = 'training_output'

            self.write_input(**kwargs)
            p_scaling = subprocess.Popen(['nnp-scaling', '100'],
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE)
            stdout, stderr = p_scaling.communicate()
            rc = p_scaling.returncode
            if rc != 0:
                error_msg = 'n2p2 exited with return code %d' % rc
                msg = stderr.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith('ERROR')
                    ][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += ', '
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            p_train = subprocess.Popen(['nnp-train'],
                                       stdout=open(output, 'w'),
                                       stderr=subprocess.PIPE)
            stdout, stderr = p_train.communicate()
            rc = p_train.returncode
            if rc != 0:
                error_msg = 'n2p2 exited with return code %d' % rc
                msg = stderr.decode("utf-8").split('\n')[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith('ERROR')
                    ][0]
                    error_msg += ', '.join(msg[error_line:])
                except Exception:
                    error_msg += ', '
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            with zopen(output) as f:
                error_lines = f.read()

            energy_rmse_pattern = re.compile(
                r'ENERGY\s*\S*\s*(\S*)\s*(\S*).*?\n')
            forces_rmse_pattern = re.compile(
                r'FORCES\s*\S*\s*(\S*)\s*(\S*).*?\n')
            errors = np.array(energy_rmse_pattern.findall(error_lines),
                              dtype=np.float).T.tolist()
            self.train_energy_rmse = errors[0]
            self.validation_energy_rmse = errors[1]

            errors = np.array(forces_rmse_pattern.findall(error_lines),
                              dtype=np.float).T.tolist()
            self.train_forces_rmse = errors[0]
            self.validation_forces_rmse = errors[1]

            for specie in self.elements:
                weights_filename = 'weights.{}.{}.out'.format(
                    str(Element(specie).number).zfill(3),
                    str(self.param['epochs']).zfill(6))
                self.weights[specie] = []
                self.bs[specie] = []
                self.weight_param[specie] = []
                self.load_weights(weights_filename, specie)
            self.load_scaler('scaling.data')

        return rc
示例#12
0
文件: _mtp.py 项目: exalearn/maml
    def evaluate(self,
                 test_structures,
                 test_energies,
                 test_forces,
                 test_stresses=None,
                 **kwargs):
        """
        Evaluate energies, forces and stresses of structures with trained
        interatomic potentials.

        Args:
            test_structures ([Structure]): List of Pymatgen Structure Objects.
            test_energies ([float]): List of DFT-calculated total energies of
                each structure in structures list.
            test_forces ([np.array]): List of DFT-calculated (m, 3) forces of
                each structure with m atoms in structures list. m can be varied
                with each single structure case.
            test_stresses (list): List of DFT-calculated (6, ) viriral stresses
                of each structure in structures list.
            kwargs: Parameters of write_param method.
        """
        if not which("mlp"):
            raise RuntimeError(
                "mlp has not been found.\n",
                "Please refer to https://mlip.skoltech.ru ",
                "for further detail.",
            )
        fitted_mtp = "fitted.mtp"
        original_file = "original.cfgs"
        predict_file = "predict.cfgs"
        test_structures, test_forces, test_stresses = check_structures_forces_stresses(
            test_structures, test_forces, test_stresses)
        predict_pool = pool_from(test_structures, test_energies, test_forces,
                                 test_stresses)

        with ScratchDir("."):
            self.write_param(
                fitted_mtp=fitted_mtp,
                Abinitio=0,
                Driver=1,
                Write_cfgs=predict_file,
                Database_filename=original_file,
                **kwargs,
            )
            original_file = self.write_cfg(original_file,
                                           cfg_pool=predict_pool)
            _, df_orig = self.read_cfgs(original_file)

            if self.version == "mlip-2":
                p = subprocess.Popen([
                    "mlp", "calc-efs", fitted_mtp, original_file, predict_file
                ],
                                     stdout=subprocess.PIPE)
            elif self.version == "mlip-dev":
                p = subprocess.Popen([
                    "mlp", "run", "mlip.ini",
                    "--filename={}".format(original_file)
                ],
                                     stdout=subprocess.PIPE)
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = "mlp exited with return code %d" % rc
                msg = stdout.decode("utf-8").split("\n")[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith("ERROR")
                    ][0]
                    error_msg += ", ".join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)
            if not os.path.exists(predict_file):
                predict_file = "_".join([predict_file, "0"])
            _, df_predict = self.read_cfgs(predict_file)
        return df_orig, df_predict
示例#13
0
文件: _mtp.py 项目: exalearn/maml
    def train(
        self,
        train_structures,
        train_energies,
        train_forces,
        train_stresses,
        unfitted_mtp="08g.mtp",
        max_dist=5,
        radial_basis_size=8,
        max_iter=500,
        energy_weight=1,
        force_weight=1e-2,
        stress_weight=1e-3,
    ):
        """
        Training data with moment tensor method.

        Args:
            train_structures ([Structure]): The list of Pymatgen Structure object.
                energies ([float]): The list of total energies of each structure
                in structures list.
            train_energies ([float]): List of total energies of each structure in
                structures list.
            train_forces ([np.array]): List of (m, 3) forces array of each structure
                with m atoms in structures list. m can be varied with each single
                structure case.
            train_stresses (list): List of (6, ) virial stresses of each structure
                in structures list.
            unfitted_mtp (str): Define the initial mtp file. Default to the mtp file
                stored in .params directory.
            max_dist (float): The actual radial cutoff.
            radial_basis_size (int): Relevant to number of radial basis function.
            max_iter (int): The number of maximum iteration.
            energy_weight (float): The weight of energy.
            force_weight (float): The weight of forces.
            stress_weight (float): The weight of stresses. Zero-weight can be assigned.
        """
        if not which("mlp"):
            raise RuntimeError(
                "mlp has not been found.\n",
                "Please refer to https://mlip.skoltech.ru",
                "for further detail.",
            )
        train_structures, train_forces, train_stresses = check_structures_forces_stresses(
            train_structures, train_forces, train_stresses)
        train_pool = pool_from(train_structures, train_energies, train_forces,
                               train_stresses)
        elements = sorted(
            set(
                itertools.chain(
                    *[struct.species for struct in train_structures])))
        self.elements = [str(element) for element in elements]

        atoms_filename = "train.cfgs"

        with ScratchDir("."):
            atoms_filename = self.write_cfg(filename=atoms_filename,
                                            cfg_pool=train_pool)

            if not unfitted_mtp:
                raise RuntimeError("No specific parameter file provided.")
            MTP_file_path = os.path.join(module_dir, "params", unfitted_mtp)
            shutil.copyfile(MTP_file_path,
                            os.path.join(os.getcwd(), unfitted_mtp))

            with open("min_dist", "w") as f:
                p = subprocess.Popen(["mlp", "mindist", atoms_filename],
                                     stdout=f)
            stdout = p.communicate()[0]

            with open("min_dist") as f:
                lines = f.readlines()
            min_dist = float(lines[-1].split(":")[1])

            with open(unfitted_mtp) as f:
                template = f.read()

            s = template % (len(
                self.elements), min_dist, max_dist, radial_basis_size)
            with open(unfitted_mtp, "w") as f:
                f.write(s)

            save_fitted_mtp = ".".join([
                unfitted_mtp.split(".")[0] + "_fitted",
                unfitted_mtp.split(".")[1]
            ])

            p = subprocess.Popen(
                [
                    "mlp",
                    "train",
                    unfitted_mtp,
                    atoms_filename,
                    "--max-iter={}".format(max_iter),
                    "--trained-pot-name={}".format(save_fitted_mtp),
                    "--curr-pot-name={}".format(unfitted_mtp),
                    "--energy-weight={}".format(energy_weight),
                    "--force-weight={}".format(force_weight),
                    "--stress-weight={}".format(stress_weight),
                    "--init-params=same",
                ],
                stdout=subprocess.PIPE,
            )
            stdout = p.communicate()[0]
            rc = p.returncode
            if rc != 0:
                error_msg = "MLP exited with return code %d" % rc
                msg = stdout.decode("utf-8").split("\n")[:-1]
                try:
                    error_line = [
                        i for i, m in enumerate(msg) if m.startswith("ERROR")
                    ][0]
                    error_msg += ", ".join(msg[error_line:])
                except Exception:
                    error_msg += msg[-1]
                raise RuntimeError(error_msg)

            def load_config(filename):
                param = OrderedDict()
                with open(filename, "r") as f:
                    lines = f.readlines()
                param["safe"] = [line.rstrip() for line in lines[:-2]]
                for line in lines[-2:]:
                    key = line.rstrip().split(" = ")[0]
                    value = json.loads(line.rstrip().split(" = ")[1].replace(
                        "{", "[").replace("}", "]"))
                    param[key] = value
                return param

            self.param = load_config(save_fitted_mtp)
        return rc