Skip to content
Snippets Groups Projects
Commit 8074eed3 authored by Christoph Groth's avatar Christoph Groth
Browse files

use the term (lead) interface (sites) instead of lead neighbors

This new nomenclature avoids the confusion between "lead neighbors" and "site
neighbors".
parent 94d16fd0
No related branches found
No related tags found
No related merge requests found
...@@ -20,10 +20,6 @@ class Lead(object): ...@@ -20,10 +20,6 @@ class Lead(object):
fermi_energy) fermi_energy)
class System(kwant.system.FiniteSystem): class System(kwant.system.FiniteSystem):
# Override abstract attributes.
graph = None
lead_neighbor_seqs = None
def __init__(self, shape, hopping, def __init__(self, shape, hopping,
potential=0, lead_potentials=(0, 0), potential=0, lead_potentials=(0, 0),
return_scalars_as_matrix=True): return_scalars_as_matrix=True):
...@@ -64,13 +60,13 @@ class System(kwant.system.FiniteSystem): ...@@ -64,13 +60,13 @@ class System(kwant.system.FiniteSystem):
g.add_edges(edges) g.add_edges(edges)
self.graph = g.compressed() self.graph = g.compressed()
self.lead_neighbor_seqs = [] self.lead_interfaces = []
for x in [0, shape[0] - 1]: for x in [0, shape[0] - 1]:
# We have to use list here, as numpy.array does not understand # We have to use list here, as numpy.array does not understand
# generators. # generators.
lead_neighbors = list(self.nodeid_from_pos((x, y)) interface = list(self.nodeid_from_pos((x, y))
for y in xrange(shape[1])) for y in xrange(shape[1]))
self.lead_neighbor_seqs.append(np.array(lead_neighbors)) self.lead_interfaces.append(np.array(interface))
self.leads = [Lead(shape[1], hopping, lead_potentials[i]) self.leads = [Lead(shape[1], hopping, lead_potentials[i])
for i in range(2)] for i in range(2)]
......
...@@ -28,9 +28,9 @@ def test_hamiltonian(): ...@@ -28,9 +28,9 @@ def test_hamiltonian():
def test_self_energy(): def test_self_energy():
sys = square.System((2, 4), 1) sys = square.System((2, 4), 1)
for lead in xrange(len(sys.lead_neighbor_seqs)): for lead in xrange(len(sys.lead_interfaces)):
n_orb = sum( n_orb = sum(
sys.num_orbitals(site) for site in sys.lead_neighbor_seqs[lead]) sys.num_orbitals(site) for site in sys.lead_interfaces[lead])
se = sys.self_energy(lead, 0) se = sys.self_energy(lead, 0)
assert_equal(len(se.shape), 2) assert_equal(len(se.shape), 2)
assert_equal(se.shape[0], se.shape[1]) assert_equal(se.shape[0], se.shape[1])
......
...@@ -299,13 +299,13 @@ class Lead(object): ...@@ -299,13 +299,13 @@ class Lead(object):
Instance Variables Instance Variables
------------------ ------------------
neighbors : sequence of sites interface : sequence of sites
""" """
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
def check_neighbors(self): def check_interface(self):
if len(self.neighbors) == 0: if len(self.interface) == 0:
raise ValueError('Lead is not connected (no neighbors).') raise ValueError('Lead is not connected (no interface sites).')
@abc.abstractmethod @abc.abstractmethod
def finalized(): def finalized():
...@@ -324,7 +324,8 @@ class Lead(object): ...@@ -324,7 +324,8 @@ class Lead(object):
The method ``self_energy`` of the finalized lead must return a square The method ``self_energy`` of the finalized lead must return a square
matrix of appropriate size. matrix of appropriate size.
The order of neighbors is assumed to be preserved during finalization. The order of interface sites is assumed to be preserved during
finalization.
""" """
pass pass
...@@ -338,7 +339,7 @@ class BuilderLead(Lead): ...@@ -338,7 +339,7 @@ class BuilderLead(Lead):
The tight-binding system of a lead. It has to possess appropriate The tight-binding system of a lead. It has to possess appropriate
symmetry, and it may not contain hoppings between further than symmetry, and it may not contain hoppings between further than
neighboring lead slices. neighboring lead slices.
neighbors : sequence of `Site` instances interface : sequence of `Site` instances
Sequence of sites in the scattering region to which the lead is Sequence of sites in the scattering region to which the lead is
attached. attached.
...@@ -349,24 +350,24 @@ class BuilderLead(Lead): ...@@ -349,24 +350,24 @@ class BuilderLead(Lead):
the symmetry vector (i.e. the lead is 'leaving' the system and starts the symmetry vector (i.e. the lead is 'leaving' the system and starts
with a hopping). with a hopping).
The given order of neighbors is preserved throughout finalization. The given order of interface sites is preserved throughout finalization.
Every system has an attribute `leads`, which stores a list of Every system has an attribute `leads`, which stores a list of
`BuilderLead` objects with all the information about the leads that are `BuilderLead` objects with all the information about the leads that are
attached. attached.
""" """
def __init__(self, builder, neighbors): def __init__(self, builder, interface):
self.builder = builder self.builder = builder
self.neighbors = tuple(neighbors) self.interface = tuple(interface)
self.check_neighbors() self.check_interface()
def finalized(self): def finalized(self):
"""Return a `kwant.system.InfiniteSystem` corresponding to the """Return a `kwant.system.InfiniteSystem` corresponding to the
compressed lead. compressed lead.
The order of neighbors is kept during finalization. The order of interface sites is kept during finalization.
""" """
return self.builder._finalized_infinite(self.neighbors) return self.builder._finalized_infinite(self.interface)
class SelfEnergy(Lead): class SelfEnergy(Lead):
...@@ -375,14 +376,14 @@ class SelfEnergy(Lead): ...@@ -375,14 +376,14 @@ class SelfEnergy(Lead):
Parameters Parameters
---------- ----------
self_energy_func : function self_energy_func : function
Function which returns the self energy matrix for the neighbors given Function which returns the self energy matrix for the interface sites
the energy. given the energy.
neighbors : sequence of `Site` instances interface : sequence of `Site` instances
""" """
def __init__(self, self_energy_func, neighbors): def __init__(self, self_energy_func, interface):
self.self_energy_func = self_energy_func self.self_energy_func = self_energy_func
self.neighbors = tuple(neighbors) self.interface = tuple(interface)
self.check_neighbors() self.check_interface()
def finalized(self): def finalized(self):
"""Trivial finalization: the object is returned itself.""" """Trivial finalization: the object is returned itself."""
...@@ -508,9 +509,9 @@ class Builder(object): ...@@ -508,9 +509,9 @@ class Builder(object):
The behavior of builders with a symmetry is slightly more sophisticated. The behavior of builders with a symmetry is slightly more sophisticated.
First of all, it is implicitly assumed throughout kwant that **every** First of all, it is implicitly assumed throughout kwant that **every**
function assigned as a value to a builder with a symmetry possesses the function assigned as a value to a builder with a symmetry possesses the
same symmetry. Secondly, all keys are mapped to the fundamental before same symmetry. Secondly, all keys are mapped to the fundamental domain
storing them. This may produce confusing results when neighbors of a site before storing them. This may produce confusing results when neighbors of
are queried. a site are queried.
The methods `possible_hoppings` and `attach_lead` *work* only if the sites The methods `possible_hoppings` and `attach_lead` *work* only if the sites
affected by them have tags which are sequences of integers. They *make affected by them have tags which are sequences of integers. They *make
...@@ -797,17 +798,17 @@ class Builder(object): ...@@ -797,17 +798,17 @@ class Builder(object):
if site not in self.H: if site not in self.H:
continue continue
while site: while site:
pneighbors = tuple(self._out_neighbors(site)) neighbors = tuple(self._out_neighbors(site))
if pneighbors: if neighbors:
assert len(pneighbors) == 1 assert len(neighbors) == 1
pneighbor = pneighbors[0] neighbor = neighbors[0]
self._del_edge(pneighbor, site) self._del_edge(neighbor, site)
if self._out_degree(pneighbor) > 1: if self._out_degree(neighbor) > 1:
pneighbor = False neighbor = False
else: else:
pneighbor = False neighbor = False
del self.H[site] del self.H[site]
site = pneighbor site = neighbor
def __iter__(self): def __iter__(self):
"""Return an iterator over all sites and hoppings.""" """Return an iterator over all sites and hoppings."""
...@@ -970,7 +971,7 @@ class Builder(object): ...@@ -970,7 +971,7 @@ class Builder(object):
min_dom = min(all_doms) min_dom = min(all_doms)
del all_doms del all_doms
neighbors = set() interface = set()
added = set() added = set()
# Initialize flood-fill: create the outermost sites. # Initialize flood-fill: create the outermost sites.
for site in H: for site in H:
...@@ -980,7 +981,7 @@ class Builder(object): ...@@ -980,7 +981,7 @@ class Builder(object):
if neighbor not in self: if neighbor not in self:
self[neighbor] = lead_builder[neighbor] self[neighbor] = lead_builder[neighbor]
added.add(neighbor) added.add(neighbor)
neighbors.add(neighbor) interface.add(neighbor)
# Do flood-fill. # Do flood-fill.
covered = True covered = True
...@@ -1006,7 +1007,7 @@ class Builder(object): ...@@ -1006,7 +1007,7 @@ class Builder(object):
self[site_new, site] = lead_builder[site_new, site] self[site_new, site] = lead_builder[site_new, site]
added = added2 added = added2
self.leads.append(BuilderLead(lead_builder, list(neighbors))) self.leads.append(BuilderLead(lead_builder, tuple(interface)))
return len(self.leads) - 1 return len(self.leads) - 1
def finalized(self): def finalized(self):
...@@ -1059,7 +1060,7 @@ class Builder(object): ...@@ -1059,7 +1060,7 @@ class Builder(object):
#### Connect leads. #### Connect leads.
finalized_leads = [] finalized_leads = []
lead_neighbor_seqs = [] lead_interfaces = []
for lead_nr, lead in enumerate(self.leads): for lead_nr, lead in enumerate(self.leads):
try: try:
finalized_leads.append(lead.finalized()) finalized_leads.append(lead.finalized())
...@@ -1067,8 +1068,8 @@ class Builder(object): ...@@ -1067,8 +1068,8 @@ class Builder(object):
msg = 'Problem finalizing lead {0}:' msg = 'Problem finalizing lead {0}:'
e.args = (' '.join((msg.format(lead_nr),) + e.args),) e.args = (' '.join((msg.format(lead_nr),) + e.args),)
raise raise
lns = [id_by_site[neighbor] for neighbor in lead.neighbors] interface = [id_by_site[isite] for isite in lead.interface]
lead_neighbor_seqs.append(np.array(lns)) lead_interfaces.append(np.array(interface))
#### Assemble and return result. #### Assemble and return result.
result = FiniteSystem() result = FiniteSystem()
...@@ -1078,24 +1079,24 @@ class Builder(object): ...@@ -1078,24 +1079,24 @@ class Builder(object):
result.hoppings = [self._get_edge(sites[tail], sites[head]) result.hoppings = [self._get_edge(sites[tail], sites[head])
for tail, head in g] for tail, head in g]
result.onsite_hamiltonians = [self.H[site][1] for site in sites] result.onsite_hamiltonians = [self.H[site][1] for site in sites]
result.lead_neighbor_seqs = lead_neighbor_seqs result.lead_interfaces = lead_interfaces
result.symmetry = self.symmetry result.symmetry = self.symmetry
return result return result
def _finalized_infinite(self, order_of_neighbors=None): def _finalized_infinite(self, interface_order=None):
""" """
Finalize this builder instance which has to have exactly a single Finalize this builder instance which has to have exactly a single
symmetry direction. symmetry direction.
If order_of_neighbors is not set, the order of the neighbors in the If interface_order is not set, the order of the interface sites in the
finalized system will be arbitrary. If order_of_neighbors is set to a finalized system will be arbitrary. If interface_order is set to a
sequence of neighbor sites, this order will be kept. sequence of interface sites, this order will be kept.
""" """
sym = self.symmetry sym = self.symmetry
assert sym.num_directions == 1 assert sym.num_directions == 1
#### For each site of the fundamental domain, determine whether it has #### For each site of the fundamental domain, determine whether it has
#### neighbors or not. #### neighbors in the previous domain or not.
lsites_with = [] # Fund. domain sites with neighbors in prev. dom lsites_with = [] # Fund. domain sites with neighbors in prev. dom
lsites_without = [] # Remaining sites of the fundamental domain lsites_without = [] # Remaining sites of the fundamental domain
for tail in self.H: # Loop over all sites of the fund. domain. for tail in self.H: # Loop over all sites of the fund. domain.
...@@ -1116,42 +1117,42 @@ class Builder(object): ...@@ -1116,42 +1117,42 @@ class Builder(object):
### Create list of sites and a lookup table ### Create list of sites and a lookup table
minus_one = ta.array((-1,)) minus_one = ta.array((-1,))
plus_one = ta.array((1,)) plus_one = ta.array((1,))
if order_of_neighbors is None: if interface_order is None:
neighbors = [sym.act(minus_one, s) for s in lsites_with] interface = [sym.act(minus_one, s) for s in lsites_with]
else: else:
shift = ta.array((-sym.which(order_of_neighbors[0])[0] - 1,)) shift = ta.array((-sym.which(interface_order[0])[0] - 1,))
lsites_with_set = set(lsites_with) lsites_with_set = set(lsites_with)
lsites_with = [] lsites_with = []
neighbors = [] interface = []
for out_of_place_neighbor in order_of_neighbors: for shifted_iface_site in interface_order:
# Shift the neighbor domain before the fundamental domain. # Shift the interface domain before the fundamental domain.
# That's the right place for the neighbors of a lead to be, but # That's the right place for the interface of a lead to be, but
# the neighbors in order_of_neighbors might live in a different # the sites of interface_order might live in a different
# domain. # domain.
neighbor = sym.act(shift, out_of_place_neighbor) iface_site = sym.act(shift, shifted_iface_site)
lsite = sym.act(plus_one, neighbor) lsite = sym.act(plus_one, iface_site)
try: try:
lsites_with_set.remove(lsite) lsites_with_set.remove(lsite)
except KeyError: except KeyError:
if (-sym.which(out_of_place_neighbor)[0] - 1,) != shift: if (-sym.which(shifted_iface_site)[0] - 1,) != shift:
raise ValueError( raise ValueError(
'The sites in order_of_neighbors do not all ' 'The sites in interface_order do not all '
'belong to the same lead slice.') 'belong to the same lead slice.')
else: else:
raise ValueError('A site in order_of_neighbors is ' raise ValueError('A site in interface_order is not an '
'not a neighbor:\n' + str(neighbor)) 'interface site:\n' + str(iface_site))
neighbors.append(neighbor) interface.append(iface_site)
lsites_with.append(lsite) lsites_with.append(lsite)
if lsites_with_set: if lsites_with_set:
raise ValueError( raise ValueError(
'order_of_neighbors did not contain all neighbors.') 'interface_order did not contain all interface sites.')
del lsites_with_set del lsites_with_set
sites = lsites_with + lsites_without + neighbors sites = lsites_with + lsites_without + interface
del lsites_with del lsites_with
del lsites_without del lsites_without
del neighbors del interface
id_by_site = {} id_by_site = {}
for site_id, site in enumerate(sites): for site_id, site in enumerate(sites):
id_by_site[site] = site_id id_by_site[site] = site_id
......
...@@ -41,8 +41,8 @@ def test_rectangle(): ...@@ -41,8 +41,8 @@ def test_rectangle():
fsys = sys.finalized() fsys = sys.finalized()
slices = slicer.slice(fsys.graph, slices = slicer.slice(fsys.graph,
fsys.lead_neighbor_seqs[0], fsys.lead_interfaces[0],
fsys.lead_neighbor_seqs[1]) fsys.lead_interfaces[1])
# In the rectangle case, the slicing is very constricted and # In the rectangle case, the slicing is very constricted and
# we know that all slices must have the same shape. # we know that all slices must have the same shape.
......
...@@ -277,7 +277,7 @@ def iterate_lead_sites_builder(syst, lead_copies): ...@@ -277,7 +277,7 @@ def iterate_lead_sites_builder(syst, lead_copies):
if not isinstance(lead, builder.BuilderLead): if not isinstance(lead, builder.BuilderLead):
continue continue
sym = lead.builder.symmetry sym = lead.builder.symmetry
shift = sym.which(lead.neighbors[0]) + 1 shift = sym.which(lead.interface[0]) + 1
for i in xrange(lead_copies): for i in xrange(lead_copies):
for site in lead.builder.sites(): for site in lead.builder.sites():
...@@ -289,7 +289,7 @@ def iterate_lead_hoppings_builder(syst, lead_copies): ...@@ -289,7 +289,7 @@ def iterate_lead_hoppings_builder(syst, lead_copies):
if not isinstance(lead, builder.BuilderLead): if not isinstance(lead, builder.BuilderLead):
continue continue
sym = lead.builder.symmetry sym = lead.builder.symmetry
shift = sym.which(lead.neighbors[0]) + 1 shift = sym.which(lead.interface[0]) + 1
for i in xrange(lead_copies): for i in xrange(lead_copies):
for site1, site2 in lead.builder.hoppings(): for site1, site2 in lead.builder.hoppings():
......
...@@ -135,10 +135,10 @@ class SparseSolver(object): ...@@ -135,10 +135,10 @@ class SparseSolver(object):
splhsmat = getattr(sp, self.lhsformat + '_matrix') splhsmat = getattr(sp, self.lhsformat + '_matrix')
sprhsmat = getattr(sp, self.rhsformat + '_matrix') sprhsmat = getattr(sp, self.rhsformat + '_matrix')
if not sys.lead_neighbor_seqs: if not sys.lead_interfaces:
raise ValueError('System contains no leads.') raise ValueError('System contains no leads.')
lhs, norb = sys.hamiltonian_submatrix( lhs, norb = sys.hamiltonian_submatrix(sparse=True,
sparse=True, return_norb=True)[:2] return_norb=True)[:2]
lhs = getattr(lhs, 'to' + self.lhsformat)() lhs = getattr(lhs, 'to' + self.lhsformat)()
lhs = lhs - energy * sp.identity(lhs.shape[0], format=self.lhsformat) lhs = lhs - energy * sp.identity(lhs.shape[0], format=self.lhsformat)
...@@ -146,7 +146,8 @@ class SparseSolver(object): ...@@ -146,7 +146,8 @@ class SparseSolver(object):
if np.any(abs((lhs - lhs.T.conj()).data) > 1e-13): if np.any(abs((lhs - lhs.T.conj()).data) > 1e-13):
raise ValueError('System Hamiltonian is not Hermitian.') raise ValueError('System Hamiltonian is not Hermitian.')
offsets = np.zeros(norb.shape[0] + 1, int) offsets = np.empty(norb.shape[0] + 1, int)
offsets[0] = 0
offsets[1 :] = np.cumsum(norb) offsets[1 :] = np.cumsum(norb)
# Process the leads, generate the eigenvector matrices and lambda # Process the leads, generate the eigenvector matrices and lambda
...@@ -155,7 +156,7 @@ class SparseSolver(object): ...@@ -155,7 +156,7 @@ class SparseSolver(object):
kept_vars = [] kept_vars = []
rhs = [] rhs = []
lead_info = [] lead_info = []
for leadnum, lead_neighbors in enumerate(sys.lead_neighbor_seqs): for leadnum, interface in enumerate(sys.lead_interfaces):
lead = sys.leads[leadnum] lead = sys.leads[leadnum]
if isinstance(lead, system.InfiniteSystem) and not force_realspace: if isinstance(lead, system.InfiniteSystem) and not force_realspace:
h = lead.slice_hamiltonian() h = lead.slice_hamiltonian()
...@@ -189,21 +190,21 @@ class SparseSolver(object): ...@@ -189,21 +190,21 @@ class SparseSolver(object):
# Construct a matrix of 1's that translates the # Construct a matrix of 1's that translates the
# inter-slice hopping to a proper hopping # inter-slice hopping to a proper hopping
# from the system to the lead. # from the system to the lead.
neighbors = np.r_[tuple(np.arange(offsets[i], offsets[i + 1]) iface_orbs = np.r_[tuple(slice(offsets[i], offsets[i + 1])
for i in lead_neighbors)] for i in interface)]
coords = np.r_[[np.arange(neighbors.size)], [neighbors]] coords = np.r_[[np.arange(iface_orbs.size)], [iface_orbs]]
tmp = sp.csc_matrix((np.ones(neighbors.size), coords), transf = sp.csc_matrix((np.ones(iface_orbs.size), coords),
shape=(neighbors.size, lhs.shape[0])) shape=(iface_orbs.size, lhs.shape[0]))
if svd is not None: if svd is not None:
v_sp = sp.csc_matrix(svd[2].T.conj()) * tmp v_sp = sp.csc_matrix(svd[2].T.conj()) * transf
vdaguout_sp = tmp.T * sp.csc_matrix(np.dot(svd[2] * svd[1], vdaguout_sp = transf.T * \
u_out)) sp.csc_matrix(np.dot(svd[2] * svd[1], u_out))
lead_mat = - ulinv_out lead_mat = - ulinv_out
else: else:
v_sp = tmp v_sp = transf
vdaguout_sp = tmp.T * sp.csc_matrix(np.dot(v.T.conj(), vdaguout_sp = transf.T * sp.csc_matrix(np.dot(v.T.conj(),
u_out)) u_out))
lead_mat = - ulinv_out lead_mat = - ulinv_out
lhs = sp.bmat([[lhs, vdaguout_sp], [v_sp, lead_mat]], lhs = sp.bmat([[lhs, vdaguout_sp], [v_sp, lead_mat]],
...@@ -211,10 +212,10 @@ class SparseSolver(object): ...@@ -211,10 +212,10 @@ class SparseSolver(object):
if leadnum in in_leads and nprop > 0: if leadnum in in_leads and nprop > 0:
if svd: if svd:
vdaguin_sp = tmp.T * sp.csc_matrix( vdaguin_sp = transf.T * sp.csc_matrix(
-np.dot(svd[2] * svd[1], u_in)) -np.dot(svd[2] * svd[1], u_in))
else: else:
vdaguin_sp = tmp.T * sp.csc_matrix( vdaguin_sp = transf.T * sp.csc_matrix(
-np.dot(v.T.conj(), u_in)) -np.dot(v.T.conj(), u_in))
# defer formation of the real matrix until the proper # defer formation of the real matrix until the proper
...@@ -226,8 +227,8 @@ class SparseSolver(object): ...@@ -226,8 +227,8 @@ class SparseSolver(object):
else: else:
sigma = lead.self_energy(energy) sigma = lead.self_energy(energy)
lead_info.append(sigma) lead_info.append(sigma)
indices = np.r_[tuple(range(offsets[i], offsets[i + 1]) for i indices = np.r_[tuple(slice(offsets[i], offsets[i + 1])
in lead_neighbors)] for i in interface)]
assert sigma.shape == 2 * indices.shape assert sigma.shape == 2 * indices.shape
y, x = np.meshgrid(indices, indices) y, x = np.meshgrid(indices, indices)
sig_sparse = splhsmat((sigma.flat, [x.flat, y.flat]), sig_sparse = splhsmat((sigma.flat, [x.flat, y.flat]),
...@@ -321,7 +322,7 @@ class SparseSolver(object): ...@@ -321,7 +322,7 @@ class SparseSolver(object):
expensive and can be less stable. expensive and can be less stable.
""" """
n = len(sys.lead_neighbor_seqs) n = len(sys.lead_interfaces)
if in_leads is None: if in_leads is None:
in_leads = range(n) in_leads = range(n)
if out_leads is None: if out_leads is None:
......
...@@ -229,10 +229,10 @@ def test_tricky_singular_hopping(solve): ...@@ -229,10 +229,10 @@ def test_tricky_singular_hopping(solve):
lead = kwant.Builder(kwant.TranslationalSymmetry([(4, 0)])) lead = kwant.Builder(kwant.TranslationalSymmetry([(4, 0)]))
lead.default_site_group = system.default_site_group = square lead.default_site_group = system.default_site_group = square
neighbors = [] interface = []
for i in xrange(n): for i in xrange(n):
site = square(-1, i) site = square(-1, i)
neighbors.append(site) interface.append(site)
system[site] = 0 system[site] = 0
for j in xrange(4): for j in xrange(4):
lead[j, i] = 0 lead[j, i] = 0
...@@ -245,7 +245,7 @@ def test_tricky_singular_hopping(solve): ...@@ -245,7 +245,7 @@ def test_tricky_singular_hopping(solve):
lead[(j, i), (j+1, i)] = -1 lead[(j, i), (j+1, i)] = -1
del lead[(1, 0), (2, 0)] del lead[(1, 0), (2, 0)]
system.leads.append(kwant.builder.BuilderLead(lead, neighbors)) system.leads.append(kwant.builder.BuilderLead(lead, interface))
fsys = system.finalized() fsys = system.finalized()
s = solve(fsys, -1.3)[0] s = solve(fsys, -1.3)[0]
......
...@@ -60,21 +60,21 @@ class FiniteSystem(System): ...@@ -60,21 +60,21 @@ class FiniteSystem(System):
leads : sequence of lead objects leads : sequence of lead objects
Each lead object has to provide at least a method Each lead object has to provide at least a method
``self_energy(energy)``. ``self_energy(energy)``.
lead_neighbor_seqs : sequence of sequences of integers lead_interfaces : sequence of sequences of integers
Each sub-sequence contains the indices of the system sites to which the Each sub-sequence contains the indices of the system sites to which the
lead is connected. lead is connected.
Notes Notes
----- -----
The length of `leads` must be equal to the length of `lead_neighbor_seqs`. The length of `leads` must be equal to the length of `lead_interfaces`.
For lead ``n``, the method leads[n].self_energy must return a square matrix For lead ``n``, the method leads[n].self_energy must return a square matrix
whose size is ``sum(self.num_orbitals(neighbor) for neighbor in whose size is ``sum(self.num_orbitals(neighbor) for neighbor in
self.lead_neighbor_seqs[n])``. self.lead_interfaces[n])``.
Often, the elements of `leads` will be instances of `InfiniteSystem`. If Often, the elements of `leads` will be instances of `InfiniteSystem`. If
this is the case for lead ``n``, the sites ``lead_neighbor_seqs[n]`` match this is the case for lead ``n``, the sites ``lead_interfaces[n]`` match
the first ``len(lead_neighbor_seqs[n])`` sites of the InfiniteSystem. the first ``len(lead_interfaces[n])`` sites of the InfiniteSystem.
""" """
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
...@@ -100,7 +100,7 @@ class InfiniteSystem(System): ...@@ -100,7 +100,7 @@ class InfiniteSystem(System):
previous slice. They are included so that hoppings between slices can be previous slice. They are included so that hoppings between slices can be
represented. The N sites of the previous slice correspond to the first `N` represented. The N sites of the previous slice correspond to the first `N`
sites of the fully included slice. When an InfiniteSystem is used as a sites of the fully included slice. When an InfiniteSystem is used as a
lead, `N` acts also as the number of neighbors to which it must be lead, `N` acts also as the number of interface sites to which it must be
connected. connected.
The drawing shows three slices of an infinite system. Each slice consists The drawing shows three slices of an infinite system. Each slice consists
......
...@@ -288,8 +288,8 @@ def test_finalization(): ...@@ -288,8 +288,8 @@ def test_finalization():
sys.leads.append(builder.BuilderLead( sys.leads.append(builder.BuilderLead(
lead, (builder.Site(sg, n) for n in neighbors))) lead, (builder.Site(sg, n) for n in neighbors)))
fsys = sys.finalized() fsys = sys.finalized()
assert_equal(len(fsys.lead_neighbor_seqs), 1) assert_equal(len(fsys.lead_interfaces), 1)
assert_equal([fsys.site(i).tag for i in fsys.lead_neighbor_seqs[0]], assert_equal([fsys.site(i).tag for i in fsys.lead_interfaces[0]],
neighbors) neighbors)
# Add a hopping to the lead which couples two next-nearest slices and check # Add a hopping to the lead which couples two next-nearest slices and check
...@@ -442,13 +442,13 @@ def test_attach_lead(): ...@@ -442,13 +442,13 @@ def test_attach_lead():
sys[(0,)] = 1 sys[(0,)] = 1
sys.attach_lead(lead0) sys.attach_lead(lead0)
assert_equal(len(list(sys.sites())), 3) assert_equal(len(list(sys.sites())), 3)
assert_equal(set(sys.leads[0].neighbors), set([gr(-1), gr(0)])) assert_equal(set(sys.leads[0].interface), set([gr(-1), gr(0)]))
sys[(-10,)] = sys[(-11,)] = 0 sys[(-10,)] = sys[(-11,)] = 0
sys.attach_lead(lead0) sys.attach_lead(lead0)
assert_equal(set(sys.leads[1].neighbors), set([gr(-10), gr(-11)])) assert_equal(set(sys.leads[1].interface), set([gr(-10), gr(-11)]))
assert_equal(len(list(sys.sites())), 5) assert_equal(len(list(sys.sites())), 5)
sys.attach_lead(lead0, gr(-5)) sys.attach_lead(lead0, gr(-5))
assert_equal(set(sys.leads[0].neighbors), set([gr(-1), gr(0)])) assert_equal(set(sys.leads[0].interface), set([gr(-1), gr(0)]))
sys.finalized() sys.finalized()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment