root / ase / calculators / interface.py @ 10
Historique | Voir | Annoter | Télécharger (4,86 ko)
1 | 1 | tkerber | import numpy as np |
---|---|---|---|
2 | 1 | tkerber | |
3 | 1 | tkerber | |
4 | 1 | tkerber | class Calculator: |
5 | 1 | tkerber | """Class for demonstrating the ASE-calculator interface.
|
6 | 1 | tkerber |
|
7 | 1 | tkerber | A good implementation of a calculator should store a copy of the
|
8 | 1 | tkerber | atoms object used for the last calculation. When one of the
|
9 | 1 | tkerber | *get_potential_energy*, *get_forces*, or *get_stress* methods is
|
10 | 1 | tkerber | called, the calculator should check if anything has changed since
|
11 | 1 | tkerber | the last calculation and only do the calculation if it's really
|
12 | 1 | tkerber | needed. The Atoms class implements the methods *__eq__* and
|
13 | 1 | tkerber | *__ne__* that can be used for checking identity (using *==* and
|
14 | 1 | tkerber | *!=*): Two sets of atoms are considered identical if they have the
|
15 | 1 | tkerber | same positions, atomic numbers, unit cell and periodic boundary
|
16 | 1 | tkerber | conditions."""
|
17 | 1 | tkerber | |
18 | 1 | tkerber | def get_potential_energy(self, atoms=None, force_consistent=False): |
19 | 1 | tkerber | """Return total energy.
|
20 | 1 | tkerber |
|
21 | 1 | tkerber | Both the energy extrapolated to zero Kelvin and the energy
|
22 | 1 | tkerber | consistent with the forces (the free energy) can be
|
23 | 1 | tkerber | returned."""
|
24 | 1 | tkerber | return 0.0 |
25 | 1 | tkerber | |
26 | 1 | tkerber | def get_forces(self, atoms): |
27 | 1 | tkerber | """Return the forces."""
|
28 | 1 | tkerber | return np.zeros((len(atoms), 3)) |
29 | 1 | tkerber | |
30 | 1 | tkerber | def get_stress(self, atoms): |
31 | 1 | tkerber | """Return the stress."""
|
32 | 1 | tkerber | return np.zeros((3, 3)) |
33 | 1 | tkerber | |
34 | 1 | tkerber | def calculation_required(self, atoms, quantities): |
35 | 1 | tkerber | """Check if a calculation is required.
|
36 | 1 | tkerber |
|
37 | 1 | tkerber | Check if the quantities in the *quantities* list have already
|
38 | 1 | tkerber | been calculated for the atomic configuration *atoms*. The
|
39 | 1 | tkerber | quantities can be one or more of: 'energy', 'forces', 'stress',
|
40 | 1 | tkerber | and 'magmoms'."""
|
41 | 1 | tkerber | return False |
42 | 1 | tkerber | |
43 | 1 | tkerber | def set_atoms(self, atoms): |
44 | 1 | tkerber | """Let the calculator know the atoms.
|
45 | 1 | tkerber |
|
46 | 1 | tkerber | This method is optional. If it exists, it will be called when
|
47 | 1 | tkerber | the *Atoms.set_calculator()* method is called.
|
48 | 1 | tkerber |
|
49 | 1 | tkerber | *Don't* store a reference to *atoms* - that will create a
|
50 | 1 | tkerber | cyclic reference loop! Store a copy instead."""
|
51 | 1 | tkerber | self.atoms = atoms.copy()
|
52 | 1 | tkerber | |
53 | 1 | tkerber | |
54 | 1 | tkerber | class DFTCalculator(Calculator): |
55 | 1 | tkerber | """Class for demonstrating the ASE interface to DFT-calculators."""
|
56 | 1 | tkerber | |
57 | 1 | tkerber | def get_number_of_bands(self): |
58 | 1 | tkerber | """Return the number of bands."""
|
59 | 1 | tkerber | return 42 |
60 | 1 | tkerber | |
61 | 1 | tkerber | def get_xc_functional(self): |
62 | 1 | tkerber | """Return the XC-functional identifier.
|
63 | 1 | tkerber |
|
64 | 1 | tkerber | 'LDA', 'PBE', ..."""
|
65 | 1 | tkerber | return 'LDA' |
66 | 1 | tkerber | |
67 | 1 | tkerber | def get_bz_k_points(self): |
68 | 1 | tkerber | """Return all the k-points in the 1. Brillouin zone.
|
69 | 1 | tkerber |
|
70 | 1 | tkerber | The coordinates are relative to reciprocal latice vectors."""
|
71 | 1 | tkerber | return np.zeros((1, 3)) |
72 | 1 | tkerber | |
73 | 1 | tkerber | def get_number_of_spins(self): |
74 | 1 | tkerber | """Return the number of spins in the calculation.
|
75 | 1 | tkerber |
|
76 | 1 | tkerber | Spin-paired calculations: 1, spin-polarized calculation: 2."""
|
77 | 1 | tkerber | return 1 |
78 | 1 | tkerber | |
79 | 1 | tkerber | def get_spin_polarized(self): |
80 | 1 | tkerber | """Is it a spin-polarized calculation?"""
|
81 | 1 | tkerber | return False |
82 | 1 | tkerber | |
83 | 1 | tkerber | def get_ibz_k_points(self): |
84 | 1 | tkerber | """Return k-points in the irreducible part of the Brillouin zone.
|
85 | 1 | tkerber |
|
86 | 1 | tkerber | The coordinates are relative to reciprocal latice vectors."""
|
87 | 1 | tkerber | return np.zeros((1, 3)) |
88 | 1 | tkerber | |
89 | 1 | tkerber | def get_k_point_weights(self): |
90 | 1 | tkerber | """Weights of the k-points.
|
91 | 1 | tkerber |
|
92 | 1 | tkerber | The sum of all weights is one."""
|
93 | 1 | tkerber | return np.ones(1) |
94 | 1 | tkerber | |
95 | 1 | tkerber | def get_pseudo_density(self, spin=None, pad=True): |
96 | 1 | tkerber | """Return pseudo-density array.
|
97 | 1 | tkerber |
|
98 | 1 | tkerber | If *spin* is not given, then the total density is returned.
|
99 | 1 | tkerber | Otherwise, the spin up or down density is returned (spin=0 or
|
100 | 1 | tkerber | 1)."""
|
101 | 1 | tkerber | return np.zeros((40, 40, 40)) |
102 | 1 | tkerber | |
103 | 1 | tkerber | def get_effective_potential(self, spin=0, pad=True): |
104 | 1 | tkerber | """Return pseudo-effective-potential array."""
|
105 | 1 | tkerber | return np.zeros((40, 40, 40)) |
106 | 1 | tkerber | |
107 | 1 | tkerber | def get_pseudo_wave_function(self, band=0, kpt=0, spin=0, broadcast=True, |
108 | 1 | tkerber | pad=True):
|
109 | 1 | tkerber | """Return pseudo-wave-function array."""
|
110 | 1 | tkerber | return np.zeros((40, 40, 40)) |
111 | 1 | tkerber | |
112 | 1 | tkerber | def get_eigenvalues(self, kpt=0, spin=0): |
113 | 1 | tkerber | """Return eigenvalue array."""
|
114 | 1 | tkerber | return np.arange(42, float) |
115 | 1 | tkerber | |
116 | 1 | tkerber | def get_occupation_numbers(self, kpt=0, spin=0): |
117 | 1 | tkerber | """Return occupation number array."""
|
118 | 1 | tkerber | return np.ones(42) |
119 | 1 | tkerber | |
120 | 1 | tkerber | def get_fermi_level(self): |
121 | 1 | tkerber | """Return the Fermi level."""
|
122 | 1 | tkerber | return 0.0 |
123 | 1 | tkerber | |
124 | 1 | tkerber | def initial_wannier(self, initialwannier, kpointgrid, fixedstates, |
125 | 1 | tkerber | edf, spin): |
126 | 1 | tkerber | """Initial guess for the shape of wannier functions.
|
127 | 1 | tkerber |
|
128 | 1 | tkerber | Use initial guess for wannier orbitals to determine rotation
|
129 | 1 | tkerber | matrices U and C.
|
130 | 1 | tkerber | """
|
131 | 1 | tkerber | raise NotImplementedError |
132 | 1 | tkerber | |
133 | 1 | tkerber | return c, U
|
134 | 1 | tkerber | |
135 | 1 | tkerber | def get_wannier_localization_matrix(self, nbands, dirG, kpoint, |
136 | 1 | tkerber | nextkpoint, G_I, spin): |
137 | 1 | tkerber | """Calculate integrals for maximally localized Wannier functions."""
|
138 | 1 | tkerber | |
139 | 1 | tkerber | def get_magnetic_moment(self, atoms=None): |
140 | 1 | tkerber | """Return the total magnetic moment."""
|
141 | 1 | tkerber | return self.occupation.magmom |
142 | 1 | tkerber | |
143 | 1 | tkerber | def get_number_of_grid_points(self): |
144 | 1 | tkerber | """Return the shape of arrays."""
|
145 | 1 | tkerber | return self.gd.N_c |
146 | 1 | tkerber |