Commit 912bfc95 authored by Eric Hermes's avatar Eric Hermes

Merge branch 'master' into neg_eigerr

parents 79dc90d3 afcca788
......@@ -14,5 +14,5 @@ master:
- su user -c 'gpaw test --range linalg/gemm_complex.py,lcao/dos.py'
- flake8 --exit-zero --exclude "doc/platforms/*,gpaw/lrtddft2/*" gpaw doc > f8.out
- cat f8.out | wc -l | tee nerr
- python -c "assert int(open('nerr').read()) <= 2364, 'Please run flake8 on your code'"
- python -c "assert int(open('nerr').read()) <= 2341, 'Please run flake8 on your code'"
- python -We:invalid -m compileall -f -q gpaw/
......@@ -543,8 +543,11 @@ Occupation numbers
The smearing of the occupation numbers is controlled like this::
from gpaw import GPAW, FermiDirac
calc = GPAW(..., occupations=FermiDirac(width), ...)
from gpaw import GPAW
calc = GPAW(...,
occupations={'name': 'fermi-dirac',
'width': 0.05},
...)
The distribution looks like this (width = `k_B T`):
......@@ -555,8 +558,15 @@ is 0.1 eV and the total energies are extrapolated to *T* = 0 Kelvin.
For a molecule (no periodic boundaries) the default value is ``width=0``,
which gives integer occupation numbers.
For a spin-polarized calculation, one can fix the magnetic moment at
the initial value using ``FermiDirac(width, fixmagmom=True)``.
Other distribution functions:
* ``{'name': 'marzari-vanderbilt', 'width': ...}``
* ``{'name': 'methfessel-paxton', 'width': ..., 'order': ...}``
For a spin-polarized calculation, one can fix the total magnetic moment at
the initial value using::
occupations={'name': ..., 'width': ..., 'fixmagmom': True}
.. _manual_lmax:
......
......@@ -62,6 +62,8 @@ Git master branch
* Point-group symmetries now also used for non-periodic systems.
Use ``symmetry={'point_group': False}`` if you don't want that.
* :ref:`Marzari-Vanderbilt distribution function <manual_occ>` added.
.. _setuptools: https://setuptools.readthedocs.io/en/latest/
......
......@@ -43,6 +43,7 @@ __all__ = ['GPAW',
'CG', 'Davidson', 'RMMDIIS', 'DirectLCAO',
'PoissonSolver',
'FermiDirac', 'MethfesselPaxton',
'MarzariVanderbilt',
'PW', 'LCAO', 'restart', 'FD']
......@@ -258,7 +259,8 @@ with broadcast_imports:
from gpaw.mixer import Mixer, MixerSum, MixerDif, MixerSum2
from gpaw.eigensolvers import Davidson, RMMDIIS, CG, DirectLCAO
from gpaw.poisson import PoissonSolver
from gpaw.occupations import FermiDirac, MethfesselPaxton
from gpaw.occupations import (FermiDirac, MethfesselPaxton,
MarzariVanderbilt)
from gpaw.wavefunctions.lcao import LCAO
from gpaw.wavefunctions.pw import PW
from gpaw.wavefunctions.fd import FD
......
......@@ -32,6 +32,7 @@ def hook(parser, args):
help='Run on N CPUs.')
args, extra = parser.parse_known_args(args)
if extra:
assert not args.arguments
args.arguments = extra
if args.command == 'python':
......
import argparse
import runpy
import sys
......@@ -19,7 +18,7 @@ class CLICommand:
parser.add_argument('arguments', metavar='ARG',
help='Arguments passed to program in '
'sys.argv[1:].',
nargs=argparse.REMAINDER)
nargs=-1)
@staticmethod
def run(args):
......
......@@ -2,7 +2,8 @@ from ase.cli.run import Runner, str2dict, CLICommand as ASECLICommand
from gpaw import GPAW
from gpaw.mixer import Mixer, MixerSum
from gpaw.occupations import FermiDirac, MethfesselPaxton
from gpaw.occupations import (FermiDirac, MethfesselPaxton,
MarzariVanderbilt)
from gpaw.wavefunctions.pw import PW
......@@ -20,6 +21,7 @@ class GPAWRunner(Runner):
'PW': PW,
'FermiDirac': FermiDirac,
'MethfesselPaxton': MethfesselPaxton,
'MarzariVanderbilt': MarzariVanderbilt,
'Mixer': Mixer,
'MixerSum': MixerSum}
parameters = str2dict(self.args.parameters, parameter_namespace)
......
......@@ -18,6 +18,8 @@ def create_occupation_number_object(name, **kwargs):
return FermiDirac(**kwargs)
if name == 'methfessel-paxton':
return MethfesselPaxton(**kwargs)
if name == 'marzari-vanderbilt':
return MarzariVanderbilt(**kwargs)
if name == 'orbital-free':
return TFOccupations()
raise ValueError('Unknown occupation number object name: ' + name)
......@@ -625,6 +627,46 @@ class MethfesselPaxton(SmoothDistribution):
return E - self.e_entropy / (self.order + 2)
class MarzariVanderbilt(SmoothDistribution):
def __init__(self, width, fixmagmom=False):
SmoothDistribution.__init__(self, width, fixmagmom)
def todict(self):
dct = SmoothDistribution.todict(self)
dct['name'] = 'marzari-vanderbilt'
return dct
def __str__(self):
s = ' Marzari-Vanderbilt: width={0:.4f} eV\n'.format(
self.width * Hartree)
return SmoothDistribution.__str__(self) + s
def distribution(self, kpt, fermilevel):
x = (kpt.eps_n - fermilevel) / self.width
x = x.clip(-100, 100)
expterm = np.exp(-(x + (1 / np.sqrt(2)))**2)
z = expterm / np.sqrt(2 * np.pi) + 0.5 * (1 - erf(1. / np.sqrt(2) + x))
kpt.f_n[:] = kpt.weight * z
n = kpt.f_n.sum()
dnde = expterm * (2 + np.sqrt(2) * x) / np.sqrt(np.pi)
dnde = dnde.sum() * kpt.weight / self.width
s = expterm * (1 + np.sqrt(2) * x) / (2 * np.sqrt(np.pi))
e_entropy = -kpt.weight * s.sum() * self.width
sign = 1 - kpt.s * 2
return np.array([n, dnde, n * sign, e_entropy])
def extrapolate_energy_to_zero_width(self, E):
# According to Nicola Marzari, one should not extrapolate M-V energies
# https://lists.quantum-espresso.org/pipermail/users/2005-October/003170.html
return E
class FixedOccupations(ZeroKelvin):
def __init__(self, occupation):
self.occupation = np.array(occupation)
......
......@@ -2,7 +2,7 @@ def create_tasks():
from myqueue.task import task
return [task('[email protected]:5h'),
task('submit.agts.py', deps='gaps.py'),
task('molecule.py', cores=8, tmax='5h')]
task('molecules.py', cores=8, tmax='5h')]
if __name__ == '__main__':
......
......@@ -13,7 +13,7 @@ from gpaw.spline import Spline
if world.size > 1:
from unittest import SkipTest
raise SkiipTest
raise SkipTest
N = 20
L = 2.5
......
from __future__ import print_function
import numpy as np
from ase.units import Hartree
from gpaw.occupations import FermiDirac, MethfesselPaxton, occupation_numbers
from gpaw.occupations import (FermiDirac, MethfesselPaxton,
MarzariVanderbilt, occupation_numbers)
class KPoint:
......@@ -39,6 +40,7 @@ for w in [0.1, 0.5]:
test(FermiDirac(w))
for n in range(4):
test(MethfesselPaxton(w, n))
test(MarzariVanderbilt(w))
occ = {'name': 'fermi-dirac', 'width': 0.1}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment