def energy(self, input_representation):
        '''Input_representation is the M matrix representation'''

        rep_vector = input_representation.rep_vector

        diffs = -self.training_set + rep_vector

        norms = np.linalg.norm(diffs, axis=1)

        exponential_vector = np.exp(-self.gamma * norms**2)

        potential = np.sum(exponential_vector * self.alphas)

        if self.baseline is not None:

            mol = ase.Atoms(input_representation.input_charge)
            mol.set_positions(input_representation.input_structure)
            mol.set_calculator(self.baseline)

            self.baseline.calculate(mol)

            baseline_energy = mol.get_potential_energy()

        else:

            baseline_energy = 0

        return self.delta_scale * potential + baseline_energy
    def compute(self, input_representation):
        '''Compute the predicted force for an input representation knowing the
        training_set and the gamma value
         '''
        # input_representation is the M matrix representation
        input_representation.generate_gradient()
        rep_vector = input_representation.rep_vector

        diffs = rep_vector - self.training_set
        # print('diffs: ', diffs[0])
        # print(np.array([np.linalg.norm(
        #     rep_vector - x) for x in self.training_set]))

        norms = np.linalg.norm(diffs, axis=1)
        # print(norms)

        exponential_vector = np.exp(-self.gamma * norms**2)
        # print(exponential_vector)

        potential = np.sum(exponential_vector * self.alphas)
        # print(potential)
        # exponential vector that come from the Kernel

        force = np.zeros([self.num_atoms, 3])
        for atomes in range(self.num_atoms):
            for coordinates in range(self.num_coordinates):

                grad_vector = input_representation.grad_vector(
                    atomes, coordinates)

                vector_sum = np.sum(diffs * grad_vector, axis=1)
                force[atomes][coordinates] = np.sum(exponential_vector * 2 *
                                                    self.alphas * self.gamma *
                                                    vector_sum)

        # potential += baseline.potential(
        #                   input_representation.coordinates())
        # force += baseline.force(input_representation.coordinates())

        if self.baseline is not None:

            mol = ase.Atoms(input_representation.input_charge)
            mol.set_positions(input_representation.input_structure)
            mol.set_calculator(self.baseline)

            baseline_energy = mol.get_potential_energy()
            baseline_force = mol.get_forces()

        else:

            baseline_energy = 0
            baseline_force = 0

        return self.delta_scale * potential + baseline_energy, self.delta_scale * force + baseline_force
def maxwell_boltzmann_distribution(atoms, temperature):
    input_velocities = np.zeros(shape=[len(atoms), 3])
    T = temperature
    kb = 1.38064852 * 1e-23
    Na = 6.02214086 * 1e23

    masse = [1e-3 * M / Na for M in ase.Atoms(atoms).get_masses()]
    standard_deviation = [np.sqrt((kb * T) / m) for m in masse]

    for i in range(len(standard_deviation)):
        for j in range(3):
            input_velocities[i][j] = 1e-5 * np.random.normal(
                loc=0, scale=standard_deviation[i], size=[1])
    return input_velocities
    def flush(self, flush_prefix):
        if len(self.moves_used) > 0:
            f = open('{}_mc_moves.dat'.format(flush_prefix), 'ab')
            np.savetxt(f,
                       np.array(list(zip(self.moves_used,
                                         self.moves_accepted))),
                       fmt='%i')
            f.close()

        f = open('{}_energies.dat'.format(flush_prefix), 'ab')
        np.savetxt(f, np.array(self.energy_traj), fmt='%.6f')
        f.close()

        for struct in self.position_traj:
            aio.write('{}_structures.xyz'.format(flush_prefix),
                      ase.Atoms(self.generation_details['atoms'],
                                positions=struct),
                      append=True)

        self.__init__(generation_details=self.generation_details,
                      flush_prefix=flush_prefix)
    def __init__(self,
                 time_step,
                 atoms,
                 KRR_force_model,
                 representation_class,
                 langevin_thermostat=False,
                 langevin_friction_coeff=10,
                 temperature=300,
                 verbose=False,
                 kb=0.0019872041):

        self.atoms = atoms
        self.time_step = time_step
        self.ase_molecule = ase.Atoms(atoms)
        self.masses = self.ase_molecule.get_masses()
        self.charges = self.ase_molecule.get_atomic_numbers()
        self.krr_force = KRR_force_model
        self.representation_class = representation_class
        self.langevin_thermostat = langevin_thermostat
        self.langevin_friction_coeff = langevin_friction_coeff
        self.temperature = temperature
        self.beta = (kb * self.temperature)**-1
        self.verbose = verbose
# Machine learning model data
charges, X_training, alphas, sigma = np.load('./ML_model_data.npy')
# Structures to start the dynamic
structures = aio.read('reservoir_structures_baseline.xyz', index=':')
# Number of replicas
num_reps = 4
# structures = []
# for i in range(num_reps-1):
#      structures.append(aio.read('./run1/hrem.rep{}__structures.xyz'.format(i), index='-1'))

# build KRR potential
atoms = structures[0].get_chemical_symbols()
num_atoms = len(atoms)

dftb_baselines = [Dftb(
     atoms=ase.Atoms(atoms),
     run_manyDftb_steps=False,
     Hamiltonian_ReadInitialCharges='No',
     Hamiltonian_MaxSCCIterations=100,
     Hamiltonian_DampXH='Yes',
     Hamiltonian_DampXHExponent=4.0,
     Hamiltonian_Eigensolver='RelativelyRobust{}',
     Hamiltonian_SCC='Yes',
     Hamiltonian_ThirdOrderFull='Yes',
     Hamiltonian_SCCTolerance=1.0E-008,
     Hamiltonian_Dispersion_='SlaterKirkwood',
     Hamiltonian_Dispersion_PolarRadiusCharge_='HybridDependentPol',
     Hamiltonian_Dispersion_PolarRadiusCharge_H='{\n CovalentRadius[Angstrom] = 0.4 \n HybridPolarisations [Angstrom^3,Angstrom,] = {\n0.386 0.396 0.400 0.410 0.410 0.410 3.5 3.5 3.5 3.5 3.5 3.5 0.8 \n }\n }',
     Hamiltonian_Dispersion_PolarRadiusCharge_C='{\n CovalentRadius[Angstrom] = 0.76 \n HybridPolarisations [Angstrom^3,Angstrom,] = {\n1.382 1.382 1.382 1.064 1.064 1.064 3.8 3.8 3.8 3.8 3.8 3.8 2.50\n }  \n}',
     Hamiltonian_Dispersion_PolarRadiusCharge_S='{\n CovalentRadius[Angstrom] = 1.02 \n HybridPolarisations [Angstrom^3,Angstrom,] = {\n3.000 3.000 3.000 3.000 3.000 3.000 4.7 4.7 4.7 4.7 4.7 4.7 4.80\n }  \n}',
 def __init__(self, atoms, calculator, time_step=1):
     self.molecule = ase.Atoms(atoms)
     self.molecule.set_calculator(calculator)
 def __init__(self, atoms):
     self.atoms = atoms
     self.nuclear_charges = ase.Atoms(symbols=atoms).get_atomic_numbers()
 def __init__(self, atoms):
     self.atoms = atoms
     self.atomic_numbers = ase.Atoms(symbols=atoms).get_atomic_numbers()
     self.mbtypes = qml.representations.get_slatm_mbtypes(
         [self.atomic_numbers])
 def __init__(self, atoms, directory, **kwargs):
     self.dftb_kwargs = kwargs
     self.atoms = ase.Atoms(atoms)
     self.directory = directory
     self.calc = adftb.Dftb(**kwargs)
     self.calc.directory = directory