Coverage for kwant/wraparound.py : 98%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Copyright 2011-2017 Kwant authors. # # This file is part of Kwant. It is subject to the license terms in the file # LICENSE.rst found in the top-level directory of this distribution and at # http://kwant-project.org/license. A list of Kwant authors can be found in # the file AUTHORS.rst at the top-level directory of this distribution and at # http://kwant-project.org/authors.
"""Decorator to memoize a function that works even with unhashable args.
This decorator will even work with functions whose args are not hashable. The cache key is made up by the hashable arguments and the ids of the non-hashable args. It is up to the user to make sure that non-hashable args do not change during the lifetime of the decorator.
This decorator will keep reevaluating functions that return None. """
"""Modify the signature of 'func', and return 'func'.
Parameters ---------- func : callable parameter_names: sequence of str Parameter names to put in the signature. These will be added as 'POSITIONAL_OR_KEYWORD' type parameters. takes_kwargs: bool If 'True', then a 'kwargs' parameter with type 'VAR_KEYWORD' is added to the end of the signature. """ for name in parameter_names] inspect.Parameter.VAR_KEYWORD))
## This wrapper is needed so that finalized systems that ## have been wrapped can be queried for their symmetry, which ## is needed for Brillouin zone calculations (plotting).
"""Replace translational symmetries by momentum parameters.
A new Builder instance is returned. By default, each symmetry is replaced by one scalar momentum parameter that is appended to the already existing arguments of the system. Optionally, one symmetry may be kept by using the `keep` argument. The momentum parameters will have names like 'k_n' where the 'n' are specified by 'coordinate_names'.
Parameters ---------- builder : `~kwant.builder.Builder` keep : int, optional Which (if any) translational symmetry to keep. coordinate_names : sequence of strings, default: ('x', 'y', 'z') The names of the coordinates along the symmetry directions of 'builder'.
Notes ----- Wraparound is stop-gap functionality until Kwant 2.x which will include support for higher-dimension translational symmetry in the low-level system format. It will be deprecated in the 2.0 release of Kwant. """
# In the following 'assert' because 'syst.hamiltonian' # should force the function to be called with *either* '*args' # or '**kwargs', not both. Also, we use different codepaths for # the two cases to avoid a performance drop when using '*args' only.
def bind_site(val):
else:
def bind_hopping_as_site(elem, val):
else:
def bind_hopping(elem, val):
else:
def bind_sum(num_sites, *vals): # Inside 'f' we do not have to split off only the used args/kwargs # because if 'val' is callable, it is guaranteed to have been wrapped # by 'bind_site', 'bind_hopping' or 'bind_hopping_as_site', which do # the disambiguation for us. for val in vals)
# construct joint signature for all 'vals'. # first the 'site' parameters name, inspect.Parameter.POSITIONAL_OR_KEYWORD) # now all the other parameters, except for the momenta # Skip parameters that exist in previously added functions, # and the momenta, which will be placed at the end. p, inspect.Parameter.POSITIONAL_OR_KEYWORD) # finally add the momenta. k, inspect.Parameter.POSITIONAL_OR_KEYWORD) 'kwargs', inspect.Parameter.VAR_KEYWORD)
raise ValueError("All symmetry directions must have a name specified " "in coordinate_names")
zip(coordinate_names, builder.symmetry.periods)]
else: # Store the names of the momentum parameters and the symmetry of the # old Builder (this will be needed for band structure plotting)
# Wrapped around system retains conservation law and chiral symmetry. # We use 'bind_site' to add the momenta arguments if required. # Set these to zero, as they can only hold @ k=0, and we currently # have no mechanism for telling the system about the existence # (or not) of a symmetry at different parameter values.
# Store lists of values, so that multiple values can be assigned to the # same site or hopping. # Every 'site' is in the FD of the original symmetry. # Move the sites to the FD of the remaining symmetry, this guarantees that # every site in the new system is an image of an original FD site translated # purely by the remaining symmetry.
# 'a' is in the FD of original symmetry. # Get translation from FD of original symmetry to 'b', # this is different from 'b_dom = sym.which(b)'. # Throw away part that is in the remaining translation direction, so we get # an element of 'sym' which is being wrapped # Pull back using the remainder, which is purely in the wrapped directions. # This guarantees that 'b_wa' is an image of an original FD site translated # purely by the remaining symmetry. # Move the hopping to the FD of the remaining symmetry
# The hopping gets wrapped-around into an onsite Hamiltonian. # Since site `a` already exists in the system, we can simply append. else: # The hopping remains a hopping. # The hopping got wrapped-around or is a function.
# Make sure that there is only one entry for each hopping # pointing in one direction, modulo the remaining translations. else:
else:
# Copy stuff into result builder, converting lists of more than one element # into summing functions.
mask_brillouin_zone=False, extend_bbox=0, file=None, show=True, dpi=None, fig_size=None, ax=None): """Plot 2D band structure of a wrapped around system.
This function is primarily useful for systems that have translational symmetry vectors that are non-orthogonal (e.g. graphene). This function will properly plot the band structure in an orthonormal basis in k-space, as opposed to in the basis of reciprocal lattice vectors (which would produce a "skewed" Brillouin zone).
If your system has orthogonal lattice vectors, you are probably better off using `kwant.plotter.spectrum`.
Parameters ---------- syst : `kwant.system.FiniteSystem` A 2D system that was finalized from a Builder produced by `kwant.wraparound.wraparound`. Note that this *must* be a finite system; so `kwant.wraparound.wraparound` should have been called with ``keep=None``. k_x, k_y : int or sequence of float, default: 31 Either a number of sampling points, or a sequence of points at which the band structure is to be evaluated, in units of inverse length. params : dict, optional Dictionary of parameter names and their values, not including the momentum parameters. mask_brillouin_zone : bool, default: False If True, then the band structure will only be plotted over the first Brillouin zone. By default the band structure is plotted over a rectangular bounding box that contains the Brillouin zone. extend_bbox : float, default: 0 Amount by which to extend the region over which the band structure is plotted, expressed as a proportion of the Brillouin zone bounding box length. i.e. ``extend_bbox=0.1`` will extend the region by 10% (in all directions). file : string or file object, optional The output file. If None, output will be shown instead. show : bool, default: False Whether ``matplotlib.pyplot.show()`` is to be called, and the output is to be shown immediately. Defaults to `True`. dpi : float, optional Number of pixels per inch. If not set the ``matplotlib`` default is used. fig_size : tuple, optional Figure size `(width, height)` in inches. If not set, the default ``matplotlib`` value is used. ax : ``matplotlib.axes.Axes`` instance, optional If `ax` is not `None`, no new figure is created, but the plot is done within the existing Axes `ax`. in this case, `file`, `show`, `dpi` and `fig_size` are ignored.
Returns ------- fig : matplotlib figure A figure with the output if `ax` is not set, else None.
Notes ----- This function produces plots where the units of momentum are inverse length. This is contrary to `kwant.plotter.bands`, where the units of momentum are inverse lattice constant.
If the lattice vectors for the symmetry of ``syst`` are not orthogonal, then part of the plotted band structure will be outside the first Brillouin zone (inside the bounding box of the brillouin zone). Setting ``mask_brillouin_zone=True`` will cause the plot to be truncated outside of the first Brillouin zone.
See Also -------- kwant.plotter.spectrum """ "'kwant.wraparound.wraparound'.") "'keep=None' when calling 'kwant.wraparound.wraparound'.")
raise ValueError("Lattice dimension must equal realspace dimension.")
# columns of B are lattice vectors # columns of A are reciprocal lattice vectors
## calculate the bounding box for the 1st Brillouin zone
# Get lattice points that neighbor the origin, in basis of lattice vectors # Add the origin to these points. # Transform to cartesian coordinates and rescale. # Will be used in 'outside_bz' function, later on. # Calculate the Voronoi cell vertices # extract bounding box
## build grid along each axis, if needed
# TODO: It is very inefficient to call 'momentum_to_lattice' once for # each point (for trivial Hamiltonians 60% of the time is spent # doing this). We should instead transform the whole grid in one call.
raise RuntimeError("Requested momentum doesn't correspond" " to any lattice momentum.")
# transform into the basis of reciprocal lattice vectors
x=('k_x', ks[0]), y=('k_y', ks[1]) if lat_ndim == 2 else None, params=params, mask=(outside_bz if mask_brillouin_zone else None), file=file, show=show, dpi=dpi, fig_size=fig_size, ax=ax) |