Ejemplo n.º 1
0
    def _calculate(self):
        unique_first_atom_nums = np.unique(
            [x['number'] for x in self._dataset['first_atoms']])
        
        for first_atom_num in unique_first_atom_nums:
            disp_pairs = []
            sets_of_forces = []
            for dataset_1st in self._dataset['first_atoms']:
                if first_atom_num != dataset_1st['number']:
                    continue
                d, f = self._collect_disp_pairs_and_forces(dataset_1st)
                disp_pairs.append(d)
                sets_of_forces.append(f)

            self._fit(first_atom_num, disp_pairs, sets_of_forces)

        rotations = self._symmetry.get_symmetry_operations()['rotations']
        translations = self._symmetry.get_symmetry_operations()['translations']

        print "ditributing fc3..."
        distribute_fc3(self._fc3,
                       unique_first_atom_nums,
                       self._lattice,
                       self._positions,
                       rotations,
                       translations,
                       self._symprec,
                       self._verbose)
Ejemplo n.º 2
0
    def _calculate(self):
        unique_first_atom_nums = np.unique(
            [x['number'] for x in self._dataset['first_atoms']])

        for first_atom_num in unique_first_atom_nums:
            disp_triplets = []
            sets_of_forces = []
            for dataset_1st in self._dataset['first_atoms']:
                if first_atom_num != dataset_1st['number']:
                    continue
                d1 = dataset_1st['displacement']
                d3, f = self._collect_forces_and_disps(dataset_1st)
                disp_triplets.append(d3)
                sets_of_forces.append(f)

            self._fit(first_atom_num, disp_triplets, sets_of_forces)

        rotations = self._symmetry.get_symmetry_operations()['rotations']
        translations = self._symmetry.get_symmetry_operations()['translations']

        print "ditributing fc4..."
        distribute_fc4(self._fc4, unique_first_atom_nums, self._lattice,
                       self._positions, rotations, translations, self._symprec,
                       self._verbose)

        print "ditributing fc3..."
        distribute_fc3(self._fc3, unique_first_atom_nums, self._lattice,
                       self._positions, rotations, translations, self._symprec,
                       self._verbose)

        print "ditributing fc2..."
        distribute_force_constants(self._fc2, range(self._num_atom),
                                   unique_first_atom_nums, self._lattice,
                                   self._positions, rotations, translations,
                                   self._symprec)
Ejemplo n.º 3
0
    def _calculate(self):
        unique_first_atom_nums = np.unique(
            [x['number'] for x in self._dataset['first_atoms']])

        for first_atom_num in unique_first_atom_nums:
            disp_triplets = []
            sets_of_forces = []
            for dataset_1st in self._dataset['first_atoms']:
                if first_atom_num != dataset_1st['number']:
                    continue
                d1 = dataset_1st['displacement']
                d3, f = self._collect_forces_and_disps(dataset_1st)
                disp_triplets.append(d3)
                sets_of_forces.append(f)

            self._fit(first_atom_num, disp_triplets, sets_of_forces)

        rotations = self._symmetry.get_symmetry_operations()['rotations']
        translations = self._symmetry.get_symmetry_operations()['translations']

        print "ditributing fc4..."
        distribute_fc4(self._fc4,
                       unique_first_atom_nums,
                       self._lattice,
                       self._positions,
                       rotations,
                       translations,
                       self._symprec,
                       self._verbose)

        print "ditributing fc3..."
        distribute_fc3(self._fc3,
                       unique_first_atom_nums,
                       self._lattice,
                       self._positions,
                       rotations,
                       translations,
                       self._symprec,
                       self._verbose)

        print "ditributing fc2..."
        distribute_force_constants(self._fc2,
                                   range(self._num_atom),
                                   unique_first_atom_nums,
                                   self._lattice,
                                   self._positions,
                                   rotations,
                                   translations,
                                   self._symprec)
Ejemplo n.º 4
0
    def _calculate(self):
        unique_first_atom_nums = np.unique(
            [x['number'] for x in self._dataset['first_atoms']])
        
        for first_atom_num in unique_first_atom_nums:
            disp_pairs = []
            sets_of_forces = []
            for dataset_1st in self._dataset['first_atoms']:
                if first_atom_num != dataset_1st['number']:
                    continue
                d, f = self._collect_disp_pairs_and_forces(dataset_1st)
                disp_pairs.append(d)
                sets_of_forces.append(f)

            self._fit(first_atom_num, disp_pairs, sets_of_forces)

        rotations = self._symmetry.get_symmetry_operations()['rotations']
        translations = self._symmetry.get_symmetry_operations()['translations']

        print "ditributing fc3..."
        fc3 = distribute_fc3(self._fc3,
                             unique_first_atom_nums,
                             self._lattice,
                             self._positions,
                             rotations,
                             translations,
                             self._symprec,
                             self._verbose)
        self._fc3 = fc3
Ejemplo n.º 5
0
def _get_constrained_fc3(supercell, displacements, reduced_site_sym,
                         translational_symmetry_type, is_permutation_symmetry,
                         symprec, verbose):
    """
    Two displacements and force constants calculation (e.g. DFPT)

        displacements = {'number': 3,
                         'displacement': [0.01, 0.00, 0.01]
                         'second_atoms': [{'number': 7,
                                           'displacement': [],
                                           'delta_fc2': }]}

    Three displacements and force calculation

        displacements = {'number': 3,
                         'displacement': [0.01, 0.00, 0.01]
                         'second_atoms': [{'number': 7,
                                           'displacement': [],
                                           'third_atoms': ... }]}
           third_atoms is like:
                         'third_atoms': [{'number': 56,
                                          'displacement': [],
                                          'delta_forces': ... }]}
    """
    num_atom = supercell.get_number_of_atoms()
    atom1 = displacements['number']
    disp1 = displacements['displacement']
    delta_fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3),
                         dtype='double')

    if 'delta_forces' in displacements['second_atoms'][0]:
        fc2_with_one_disp = get_constrained_fc2(
            supercell, displacements['second_atoms'], atom1, reduced_site_sym,
            translational_symmetry_type, is_permutation_symmetry, symprec)

    atom_list = np.unique([x['number'] for x in displacements['second_atoms']])
    for atom2 in atom_list:
        bond_sym = get_bond_symmetry(reduced_site_sym,
                                     supercell.get_scaled_positions(), atom1,
                                     atom2, symprec)
        disps2 = []
        delta_fc2s = []
        for disps_second in displacements['second_atoms']:
            if atom2 != disps_second['number']:
                continue
            disps2.append(disps_second['displacement'])

            if 'delta_fc2' in disps_second:
                delta_fc2s.append(disps_second['delta_fc2'])
            else:
                direction = np.dot(disps_second['displacement'],
                                   np.linalg.inv(supercell.get_cell()))
                reduced_bond_sym = get_reduced_site_symmetry(
                    bond_sym, direction, symprec)

                delta_fc2s.append(
                    get_delta_fc2(disps_second['third_atoms'], atom2,
                                  fc2_with_one_disp, supercell,
                                  reduced_bond_sym,
                                  translational_symmetry_type,
                                  is_permutation_symmetry, symprec))

            if verbose > 1:
                print("Second displacements for fc4[ %d, %d, x, x ]" %
                      (atom1 + 1, atom2 + 1))
                for i, v in enumerate(disps2):
                    print "  [%7.4f %7.4f %7.4f]" % tuple(v)

        solve_fc3(delta_fc3,
                  atom2,
                  supercell,
                  bond_sym,
                  disps2,
                  delta_fc2s,
                  symprec=symprec,
                  verbose=False)

    # Shift positions according to set atom1 is at origin
    lattice = supercell.get_cell().T
    positions = supercell.get_scaled_positions()
    pos_center = positions[atom1].copy()
    positions -= pos_center

    if verbose:
        print "Expanding delta fc3"

    distribute_fc3(delta_fc3,
                   atom_list,
                   lattice,
                   positions,
                   np.array(reduced_site_sym, dtype='intc', order='C'),
                   np.zeros((len(reduced_site_sym), 3), dtype='double'),
                   symprec,
                   verbose=verbose)

    if translational_symmetry_type > 0:
        set_translational_invariance_fc3_per_index(delta_fc3)

    if is_permutation_symmetry:
        set_permutation_symmetry_fc3(delta_fc3)

    return delta_fc3
Ejemplo n.º 6
0
def _get_constrained_fc3(supercell,
                         displacements,
                         reduced_site_sym,
                         is_translational_symmetry,
                         is_permutation_symmetry,
                         symprec,
                         verbose):
    """
    Two displacements and force constants calculation (e.g. DFPT)

        displacements = {'number': 3,
                         'displacement': [0.01, 0.00, 0.01]
                         'second_atoms': [{'number': 7,
                                           'displacement': [],
                                           'delta_fc2': }]}

    Three displacements and force calculation

        displacements = {'number': 3,
                         'displacement': [0.01, 0.00, 0.01]
                         'second_atoms': [{'number': 7,
                                           'displacement': [],
                                           'third_atoms': ... }]}
           third_atoms is like:
                         'third_atoms': [{'number': 56,
                                          'displacement': [],
                                          'delta_forces': ... }]}
    """
    num_atom = supercell.get_number_of_atoms()
    atom1 = displacements['number']
    disp1 = displacements['displacement']
    fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3), dtype='double')
    atom_list_done = []

    if 'delta_forces' in displacements['second_atoms'][0]:
        fc2_with_one_disp = get_constrained_fc2(supercell,
                                                displacements['second_atoms'],
                                                atom1,
                                                reduced_site_sym,
                                                is_translational_symmetry,
                                                is_permutation_symmetry,
                                                symprec)
    
    atom_list = np.unique([x['number'] for x in displacements['second_atoms']])
    for atom2 in atom_list:
        disps2 = []
        delta_fc2s = []
        for disps_second in displacements['second_atoms']:
            if atom2 != disps_second['number']:
                continue
            atom_list_done.append(atom2)
            bond_sym = get_bond_symmetry(
                reduced_site_sym,
                supercell.get_scaled_positions(),
                atom1,
                atom2,
                symprec)
            disps2.append(disps_second['displacement'])

            if 'delta_fc2' in disps_second:
                delta_fc2s.append(disps_second['delta_fc2'])
            else:
                direction = np.dot(disps_second['displacement'],
                                   np.linalg.inv(supercell.get_cell()))
                reduced_bond_sym = get_reduced_site_symmetry(
                    bond_sym, direction, symprec)

                delta_fc2s.append(get_delta_fc2(
                        disps_second['third_atoms'],
                        atom2,
                        fc2_with_one_disp,
                        supercell,
                        reduced_bond_sym,
                        is_translational_symmetry,
                        is_permutation_symmetry,
                        symprec))
    
            if verbose > 1:
                print ("Second displacements for fc4[ %d, %d, x, x ]" %
                       (atom1 + 1, atom2 + 1))
                for i, v in enumerate(disps2):
                    print "  [%7.4f %7.4f %7.4f]" % tuple(v)

            solve_fc3(fc3,
                      atom2,
                      supercell,
                      bond_sym,
                      disps2,
                      delta_fc2s,
                      symprec=symprec)

    # Shift positions according to set atom1 is at origin
    lattice = supercell.get_cell().T
    positions = supercell.get_scaled_positions()
    pos_center = positions[atom1].copy()
    positions -= pos_center

    if verbose:
        print "(Copying delta fc3...)"
    distribute_fc3(fc3,
                   atom_list_done,
                   lattice,
                   positions,
                   np.intc(reduced_site_sym).copy(),
                   np.zeros((len(reduced_site_sym), 3), dtype='double'),
                   symprec,
                   verbose)

    if is_translational_symmetry:
        set_translational_invariance_fc3_per_index(fc3)

    if is_permutation_symmetry:
        set_permutation_symmetry_fc3(fc3)

    return fc3