From 1a077ad288892214ea05c7c3f1f617cb89e39a75 Mon Sep 17 00:00:00 2001 From: Christoph Groth <christoph.groth@cea.fr> Date: Sat, 17 Nov 2012 15:30:47 +0100 Subject: [PATCH] make showing code examples in the tutorial text robust --- .gitignore | 1 + MANIFEST.in | 2 - doc/Makefile | 3 +- doc/source/images/generate-diffs.sh | 3 +- .../source/tutorial}/1-quantum_wire.py | 24 ++++ .../tutorial}/1-quantum_wire_revisited.py | 18 +++ .../source/tutorial}/2-ab_ring.py | 10 ++ .../source/tutorial}/2-quantum_well.py | 9 ++ .../source/tutorial}/2-spin_orbit.py | 8 ++ .../source/tutorial}/3-band_structure.py | 4 + .../source/tutorial}/3-closed_system.py | 6 + .../source/tutorial}/4-graphene.py | 24 ++++ .../5-superconductor_band_structure.py | 2 + .../tutorial}/5-superconductor_transport.py | 12 ++ {tutorial => doc/source/tutorial}/README | 3 - doc/source/tutorial/tutorial1.rst | 121 +++++++++++------- doc/source/tutorial/tutorial2.rst | 65 ++++++---- doc/source/tutorial/tutorial3.rst | 25 ++-- doc/source/tutorial/tutorial4.rst | 58 +++++---- doc/source/tutorial/tutorial5.rst | 35 +++-- setup.py | 41 +++++- 21 files changed, 342 insertions(+), 132 deletions(-) rename {tutorial => doc/source/tutorial}/1-quantum_wire.py (83%) rename {tutorial => doc/source/tutorial}/1-quantum_wire_revisited.py (87%) rename {tutorial => doc/source/tutorial}/2-ab_ring.py (95%) rename {tutorial => doc/source/tutorial}/2-quantum_well.py (90%) rename {tutorial => doc/source/tutorial}/2-spin_orbit.py (95%) rename {tutorial => doc/source/tutorial}/3-band_structure.py (95%) rename {tutorial => doc/source/tutorial}/3-closed_system.py (95%) rename {tutorial => doc/source/tutorial}/4-graphene.py (88%) rename {tutorial => doc/source/tutorial}/5-superconductor_band_structure.py (98%) rename {tutorial => doc/source/tutorial}/5-superconductor_transport.py (94%) rename {tutorial => doc/source/tutorial}/README (91%) diff --git a/.gitignore b/.gitignore index 4493ae39..66870064 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ MANIFEST /kwant/*.c /kwant/*/*.c /kwant/_static_version.py +/tutorial /build /dist /doc/build diff --git a/MANIFEST.in b/MANIFEST.in index 64fcabc7..59f2d474 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -12,9 +12,7 @@ recursive-include kwant *.pxd recursive-include kwant *.c recursive-include kwant *.h recursive-include kwant test_*.py - recursive-include examples *.py -recursive-include tutorial *.py include doc/other/*[a-zA-Z] include doc/Makefile diff --git a/doc/Makefile b/doc/Makefile index 3de1f635..36a2cf09 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -119,8 +119,9 @@ doctest: # Make the image generation scripts by patching tutorial scipts. +.SECONDARY: %.py: %.py.diff - @cp ../tutorial/$(notdir $@) $(dir $@) + @grep -v '^#HIDDEN' source/tutorial/$(notdir $@) >$@ @patch $@ $< # Generation of tutorial images. This requires some make trickery, see diff --git a/doc/source/images/generate-diffs.sh b/doc/source/images/generate-diffs.sh index e68cacef..aeeb479c 100755 --- a/doc/source/images/generate-diffs.sh +++ b/doc/source/images/generate-diffs.sh @@ -6,5 +6,6 @@ for f in [0-9]-*.py; do # We use custom labels to suppress the time stamps which are unnecessary # here and would only lead to noise in version control. - diff -u --label original --label modified ../../../tutorial/$f $f >$f.diff + grep -v '#HIDDEN' ../tutorial/$f | + diff -u --label original --label modified - $f >$f.diff done diff --git a/tutorial/1-quantum_wire.py b/doc/source/tutorial/1-quantum_wire.py similarity index 83% rename from tutorial/1-quantum_wire.py rename to doc/source/tutorial/1-quantum_wire.py index 02935c56..9e8ad75a 100644 --- a/tutorial/1-quantum_wire.py +++ b/doc/source/tutorial/1-quantum_wire.py @@ -8,16 +8,23 @@ # - Making scattering region and leads # - Using the simple sparse solver for computing Landauer conductance +#HIDDEN_BEGIN_dwhx import kwant +#HIDDEN_END_dwhx # First, define the tight-binding system +#HIDDEN_BEGIN_goiq sys = kwant.Builder() +#HIDDEN_END_goiq # Here, we are only working with square lattices +#HIDDEN_BEGIN_suwo a = 1 lat = kwant.lattice.Square(a) +#HIDDEN_END_suwo +#HIDDEN_BEGIN_zfvr t = 1.0 W = 10 L = 30 @@ -35,6 +42,7 @@ for i in xrange(L): #hopping in x-direction if i > 0: sys[lat(i, j), lat(i - 1, j)] = -t +#HIDDEN_END_zfvr # Then, define the leads: @@ -42,9 +50,12 @@ for i in xrange(L): # (Note: in the current version, TranslationalSymmetry takes a # realspace vector) +#HIDDEN_BEGIN_xcmc sym_lead0 = kwant.TranslationalSymmetry([lat.vec((-1, 0))]) lead0 = kwant.Builder(sym_lead0) +#HIDDEN_END_xcmc +#HIDDEN_BEGIN_ndez for j in xrange(W): lead0[lat(0, j)] = 4 * t @@ -52,8 +63,10 @@ for j in xrange(W): lead0[lat(0, j), lat(0, j - 1)] = -t lead0[lat(1, j), lat(0, j)] = -t +#HIDDEN_END_ndez # Then the lead to the right +#HIDDEN_BEGIN_xhqc sym_lead1 = kwant.TranslationalSymmetry([lat.vec((1, 0))]) lead1 = kwant.Builder(sym_lead1) @@ -65,22 +78,30 @@ for j in xrange(W): lead1[lat(0, j), lat(0, j - 1)] = -t lead1[lat(1, j), lat(0, j)] = -t +#HIDDEN_END_xhqc # Then attach the leads to the system +#HIDDEN_BEGIN_fskr sys.attach_lead(lead0) sys.attach_lead(lead1) +#HIDDEN_END_fskr # Plot it, to make sure it's OK +#HIDDEN_BEGIN_wsgh kwant.plot(sys) +#HIDDEN_END_wsgh # Finalize the system +#HIDDEN_BEGIN_dngj sys = sys.finalized() +#HIDDEN_END_dngj # Now that we have the system, we can compute conductance +#HIDDEN_BEGIN_buzn energies = [] data = [] for ie in xrange(100): @@ -93,9 +114,11 @@ for ie in xrange(100): # lead 1 energies.append(energy) data.append(smatrix.transmission(1, 0)) +#HIDDEN_END_buzn # Use matplotlib to write output # We should see conductance steps +#HIDDEN_BEGIN_lliv from matplotlib import pyplot pyplot.figure() @@ -103,3 +126,4 @@ pyplot.plot(energies, data) pyplot.xlabel("energy [in units of t]") pyplot.ylabel("conductance [in units of e^2/h]") pyplot.show() +#HIDDEN_END_lliv diff --git a/tutorial/1-quantum_wire_revisited.py b/doc/source/tutorial/1-quantum_wire_revisited.py similarity index 87% rename from tutorial/1-quantum_wire_revisited.py rename to doc/source/tutorial/1-quantum_wire_revisited.py index 8f3202a5..2e7da1aa 100644 --- a/tutorial/1-quantum_wire_revisited.py +++ b/doc/source/tutorial/1-quantum_wire_revisited.py @@ -10,6 +10,7 @@ # Note: Does the same as tutorial1a.py, but using other features of kwant # +#HIDDEN_BEGIN_xkzy import kwant # For plotting @@ -22,33 +23,45 @@ def make_system(a=1, t=1.0, W=10, L=30): lat = kwant.lattice.Square(a) sys = kwant.Builder() +#HIDDEN_END_xkzy #### Define the scattering region. #### +#HIDDEN_BEGIN_vvjt sys[(lat(x, y) for x in range(L) for y in range(W))] = 4 * t +#HIDDEN_END_vvjt +#HIDDEN_BEGIN_nooi for hopping in lat.nearest: sys[sys.possible_hoppings(*hopping)] = -t +#HIDDEN_END_nooi #### Define the leads. #### # First the lead to the left, ... # (Note: in the current version, TranslationalSymmetry takes a # realspace vector) +#HIDDEN_BEGIN_iepx sym_lead0 = kwant.TranslationalSymmetry([lat.vec((-1, 0))]) lead0 = kwant.Builder(sym_lead0) lead0[(lat(0, j) for j in xrange(W))] = 4 * t for hopping in lat.nearest: lead0[lead0.possible_hoppings(*hopping)] = -t +#HIDDEN_END_iepx # ... then the lead to the right. We use a method that returns a copy of # `lead0` with its direction reversed. +#HIDDEN_BEGIN_xkdo lead1 = lead0.reversed() +#HIDDEN_END_xkdo #### Attach the leads and return the system. #### +#HIDDEN_BEGIN_yxot sys.attach_lead(lead0) sys.attach_lead(lead1) return sys +#HIDDEN_END_yxot +#HIDDEN_BEGIN_ayuk def plot_conductance(sys, energies): # Compute conductance @@ -62,8 +75,10 @@ def plot_conductance(sys, energies): pyplot.xlabel("energy [in units of t]") pyplot.ylabel("conductance [in units of e^2/h]") pyplot.show() +#HIDDEN_END_ayuk +#HIDDEN_BEGIN_cjel def main(): sys = make_system() @@ -75,9 +90,12 @@ def main(): # We should see conductance steps. plot_conductance(sys, energies=[0.01 * i for i in xrange(100)]) +#HIDDEN_END_cjel # Call the main function if the script gets executed (as opposed to imported). # See <http://docs.python.org/library/__main__.html>. +#HIDDEN_BEGIN_ypbj if __name__ == '__main__': main() +#HIDDEN_END_ypbj diff --git a/tutorial/2-ab_ring.py b/doc/source/tutorial/2-ab_ring.py similarity index 95% rename from tutorial/2-ab_ring.py rename to doc/source/tutorial/2-ab_ring.py index 16559d6a..52c08259 100644 --- a/tutorial/2-ab_ring.py +++ b/doc/source/tutorial/2-ab_ring.py @@ -18,6 +18,7 @@ import kwant from matplotlib import pyplot +#HIDDEN_BEGIN_eusz def make_system(a=1, t=1.0, W=10, r1=10, r2=20): # Start with an empty tight-binding system and a single square lattice. # `a` is the lattice constant (by default set to 1 for simplicity). @@ -32,11 +33,14 @@ def make_system(a=1, t=1.0, W=10, r1=10, r2=20): (x, y) = pos rsq = x ** 2 + y ** 2 return (r1 ** 2 < rsq < r2 ** 2) +#HIDDEN_END_eusz # and add the corresponding lattice points using the `shape`-function +#HIDDEN_BEGIN_lcak sys[lat.shape(ring, (0, r1 + 1))] = 4 * t for hopping in lat.nearest: sys[sys.possible_hoppings(*hopping)] = -t +#HIDDEN_END_lcak # In order to introduce a flux through the ring, we introduce a phase # on the hoppings on the line cut through one of the arms @@ -44,6 +48,7 @@ def make_system(a=1, t=1.0, W=10, r1=10, r2=20): # since we want to change the flux without modifying Builder repeatedly, # we define the modified hoppings as a function that takes the flux # through the global variable phi. +#HIDDEN_BEGIN_lvkt def fluxphase(site1, site2): return exp(1j * phi) @@ -57,9 +62,11 @@ def make_system(a=1, t=1.0, W=10, r1=10, r2=20): # Modify only those hopings in x-direction that cross the branch cut sys[(hop for hop in sys.possible_hoppings((1, 0), lat, lat) if crosses_branchcut(hop))] = fluxphase +#HIDDEN_END_lvkt #### Define the leads. #### # left lead +#HIDDEN_BEGIN_qwgr sym_lead0 = kwant.TranslationalSymmetry([lat.vec((-1, 0))]) lead0 = kwant.Builder(sym_lead0) @@ -70,14 +77,17 @@ def make_system(a=1, t=1.0, W=10, r1=10, r2=20): lead0[lat.shape(lead_shape, (0, 0))] = 4 * t for hopping in lat.nearest: lead0[lead0.possible_hoppings(*hopping)] = -t +#HIDDEN_END_qwgr # Then the lead to the right # [again, obtained using reversed()] lead1 = lead0.reversed() #### Attach the leads and return the system. #### +#HIDDEN_BEGIN_skbz sys.attach_lead(lead0) sys.attach_lead(lead1) +#HIDDEN_END_skbz return sys diff --git a/tutorial/2-quantum_well.py b/doc/source/tutorial/2-quantum_well.py similarity index 90% rename from tutorial/2-quantum_well.py rename to doc/source/tutorial/2-quantum_well.py index d51ba007..5bbead7d 100644 --- a/tutorial/2-quantum_well.py +++ b/doc/source/tutorial/2-quantum_well.py @@ -13,6 +13,10 @@ from matplotlib import pyplot # global variable governing the behavior of potential() in # make_system() +#HIDDEN The following code line is included verbatim in the tutorial text +#HIDDEN because nested code examples are not supported. Remember to update +#HIDDEN the tutorial text when you modify this line. +#HIDDEN_BEGIN_ehso pot = 0 def make_system(a=1, t=1.0, W=10, L=30, L_well=10): @@ -31,13 +35,16 @@ def make_system(a=1, t=1.0, W=10, L=30, L_well=10): return pot else: return 0 +#HIDDEN_END_ehso +#HIDDEN_BEGIN_coid def onsite(site): return 4 * t + potential(site) sys[(lat(x, y) for x in range(L) for y in range(W))] = onsite for hopping in lat.nearest: sys[sys.possible_hoppings(*hopping)] = -t +#HIDDEN_END_coid #### Define the leads. #### # First the lead to the left, ... @@ -64,6 +71,7 @@ def make_system(a=1, t=1.0, W=10, L=30, L_well=10): def plot_conductance(sys, energy, welldepths): # We specify that we want to not only read, but also write to a # global variable. +#HIDDEN_BEGIN_sqvr global pot # Compute conductance @@ -80,6 +88,7 @@ def plot_conductance(sys, energy, welldepths): pyplot.xlabel("well depth [in units of t]") pyplot.ylabel("conductance [in units of e^2/h]") pyplot.show() +#HIDDEN_END_sqvr def main(): diff --git a/tutorial/2-spin_orbit.py b/doc/source/tutorial/2-spin_orbit.py similarity index 95% rename from tutorial/2-spin_orbit.py rename to doc/source/tutorial/2-spin_orbit.py index 009132b2..a37e5acc 100644 --- a/tutorial/2-spin_orbit.py +++ b/doc/source/tutorial/2-spin_orbit.py @@ -16,13 +16,17 @@ import kwant from matplotlib import pyplot # For matrix support +#HIDDEN_BEGIN_xumz import numpy +#HIDDEN_END_xumz # define Pauli-matrices for convenience +#HIDDEN_BEGIN_hwbt sigma_0 = numpy.eye(2) sigma_x = numpy.array([[0, 1], [1, 0]]) sigma_y = numpy.array([[0, -1j], [1j, 0]]) sigma_z = numpy.array([[1, 0], [0, -1]]) +#HIDDEN_END_hwbt def make_system(a=1, t=1.0, alpha=0.5, e_z=0.08, W=10, L=30): @@ -33,6 +37,7 @@ def make_system(a=1, t=1.0, alpha=0.5, e_z=0.08, W=10, L=30): sys = kwant.Builder() #### Define the scattering region. #### +#HIDDEN_BEGIN_uxrm sys[(lat(x, y) for x in range(L) for y in range(W))] = 4 * t * sigma_0 + \ e_z * sigma_z # hoppings in x-direction @@ -41,12 +46,14 @@ def make_system(a=1, t=1.0, alpha=0.5, e_z=0.08, W=10, L=30): # hoppings in y-directions sys[sys.possible_hoppings((0, 1), lat, lat)] = -t * sigma_0 + \ 1j * alpha * sigma_x +#HIDDEN_END_uxrm #### Define the leads. #### # left lead sym_lead0 = kwant.TranslationalSymmetry([lat.vec((-1, 0))]) lead0 = kwant.Builder(sym_lead0) +#HIDDEN_BEGIN_yliu lead0[(lat(0, j) for j in xrange(W))] = 4 * t * sigma_0 + e_z * sigma_z # hoppings in x-direction lead0[lead0.possible_hoppings((1, 0), lat, lat)] = -t * sigma_0 - \ @@ -54,6 +61,7 @@ def make_system(a=1, t=1.0, alpha=0.5, e_z=0.08, W=10, L=30): # hoppings in y-directions lead0[lead0.possible_hoppings((0, 1), lat, lat)] = -t * sigma_0 + \ 1j * alpha * sigma_x +#HIDDEN_END_yliu # Then the lead to the right # (again, obtained using reverse() diff --git a/tutorial/3-band_structure.py b/doc/source/tutorial/3-band_structure.py similarity index 95% rename from tutorial/3-band_structure.py rename to doc/source/tutorial/3-band_structure.py index 8a17633c..3b8fe8e0 100644 --- a/tutorial/3-band_structure.py +++ b/doc/source/tutorial/3-band_structure.py @@ -14,6 +14,7 @@ from math import pi from matplotlib import pyplot +#HIDDEN_BEGIN_zxip def make_lead(a=1, t=1.0, W=10): # Start with an empty lead with a single square lattice lat = kwant.lattice.Square(a) @@ -32,8 +33,10 @@ def make_lead(a=1, t=1.0, W=10): lead[lat(1, j), lat(0, j)] = -t return lead +#HIDDEN_END_zxip +#HIDDEN_BEGIN_pejz def plot_bandstructure(lead, momenta): # Use the method ``energies`` of the finalized lead to compute # the bandstructure @@ -53,6 +56,7 @@ def main(): momenta = [-pi + 0.02 * pi * i for i in xrange(101)] plot_bandstructure(lead, momenta) +#HIDDEN_END_pejz # Call the main function if the script gets executed (as opposed to imported). diff --git a/tutorial/3-closed_system.py b/doc/source/tutorial/3-closed_system.py similarity index 95% rename from tutorial/3-closed_system.py rename to doc/source/tutorial/3-closed_system.py index 82361ebe..97cd7405 100644 --- a/tutorial/3-closed_system.py +++ b/doc/source/tutorial/3-closed_system.py @@ -13,7 +13,9 @@ from cmath import exp import kwant # For eigenvalue computation +#HIDDEN_BEGIN_tibv import scipy.linalg as la +#HIDDEN_END_tibv # For plotting from matplotlib import pyplot @@ -23,6 +25,7 @@ def make_system(a=1, t=1.0, r=10): # Start with an empty tight-binding system and a single square lattice. # `a` is the lattice constant (by default set to 1 for simplicity). +#HIDDEN_BEGIN_qlyd lat = kwant.lattice.Square(a) sys = kwant.Builder() @@ -46,8 +49,10 @@ def make_system(a=1, t=1.0, r=10): # It's a closed system for a change, so no leads return sys +#HIDDEN_END_qlyd +#HIDDEN_BEGIN_yvri def plot_spectrum(sys, Bfields): # global variable B controls the magnetic field global B @@ -74,6 +79,7 @@ def plot_spectrum(sys, Bfields): pyplot.xlabel("magnetic field [some arbitrary units]") pyplot.ylabel("energy [in units of t]") pyplot.show() +#HIDDEN_END_yvri def main(): diff --git a/tutorial/4-graphene.py b/doc/source/tutorial/4-graphene.py similarity index 88% rename from tutorial/4-graphene.py rename to doc/source/tutorial/4-graphene.py index 95782a81..635dedbf 100644 --- a/tutorial/4-graphene.py +++ b/doc/source/tutorial/4-graphene.py @@ -21,11 +21,14 @@ from matplotlib import pyplot # Define the graphene lattice sin_30, cos_30 = (1 / 2, sqrt(3) / 2) +#HIDDEN_BEGIN_hnla graphene = kwant.make_lattice([(1, 0), (sin_30, cos_30)], [(0, 0), (0, 1 / sqrt(3))]) a, b = graphene.sublattices +#HIDDEN_END_hnla +#HIDDEN_BEGIN_shzy def make_system(r=10, w=2.0, pot=0.1): #### Define the scattering region. #### @@ -43,18 +46,26 @@ def make_system(r=10, w=2.0, pot=0.1): return pot * tanh(d / w) sys[graphene.shape(circle, (0, 0))] = potential +#HIDDEN_END_shzy # specify the hoppings of the graphene lattice in the # format expected by possibe_hoppings() +#HIDDEN_BEGIN_hsmc hoppings = (((0, 0), b, a), ((0, 1), b, a), ((-1, 1), b, a)) +#HIDDEN_END_hsmc +#HIDDEN_BEGIN_bfwb for hopping in hoppings: sys[sys.possible_hoppings(*hopping)] = -1 +#HIDDEN_END_bfwb # Modify the scattering region +#HIDDEN_BEGIN_efut del sys[a(0, 0)] sys[a(-2, 1), b(2, 2)] = -1 +#HIDDEN_END_efut #### Define the leads. #### +#HIDDEN_BEGIN_aakh # left lead sym0 = kwant.TranslationalSymmetry([graphene.vec((-1, 0))]) @@ -80,10 +91,14 @@ def make_system(r=10, w=2.0, pot=0.1): lead1[graphene.shape(lead1_shape, (0, 0))] = pot for hopping in hoppings: lead1[lead1.possible_hoppings(*hopping)] = -1 +#HIDDEN_END_aakh +#HIDDEN_BEGIN_kmmw return sys, [lead0, lead1] +#HIDDEN_END_kmmw +#HIDDEN_BEGIN_zydk def compute_evs(sys): # Compute some eigenvalues of the closed system sparse_mat = sys.hamiltonian_submatrix(sparse=True) @@ -96,6 +111,7 @@ def compute_evs(sys): print evs except: pass +#HIDDEN_END_zydk def plot_conductance(sys, energies): @@ -124,6 +140,11 @@ def plot_bandstructure(flead, momenta): pyplot.show() +#HIDDEN The part of the following code block which begins with plotter_symbols +#HIDDEN is included verbatim in the tutorial text because nested code examples +#HIDDEN are not supported. Remember to update the tutorial text when you +#HIDDEN modify this block. +#HIDDEN_BEGIN_itkk def main(): pot = 0.1 sys, leads = make_system(pot=pot) @@ -137,9 +158,12 @@ def main(): # Plot the closed system without leads. kwant.plot(sys, symbols=plotter_symbols) +#HIDDEN_END_itkk # Compute some eigenvalues. +#HIDDEN_BEGIN_jmbi compute_evs(sys.finalized()) +#HIDDEN_END_jmbi # Attach the leads to the system. for lead in leads: diff --git a/tutorial/5-superconductor_band_structure.py b/doc/source/tutorial/5-superconductor_band_structure.py similarity index 98% rename from tutorial/5-superconductor_band_structure.py rename to doc/source/tutorial/5-superconductor_band_structure.py index 27e39d3d..a0dca9e7 100644 --- a/tutorial/5-superconductor_band_structure.py +++ b/doc/source/tutorial/5-superconductor_band_structure.py @@ -18,6 +18,7 @@ from math import pi # For plotting from matplotlib import pyplot +#HIDDEN_BEGIN_nbvn tau_x = np.array([[0, 1], [1, 0]]) tau_z = np.array([[1, 0], [0, -1]]) @@ -40,6 +41,7 @@ def make_lead(a=1, t=1.0, mu=0.7, Delta=0.1, W=10): lead[lat(1, j), lat(0, j)] = -t * tau_z return lead +#HIDDEN_END_nbvn def plot_bandstructure(lead, momenta): diff --git a/tutorial/5-superconductor_transport.py b/doc/source/tutorial/5-superconductor_transport.py similarity index 94% rename from tutorial/5-superconductor_transport.py rename to doc/source/tutorial/5-superconductor_transport.py index 977fb1e1..1e0e3bb3 100644 --- a/tutorial/5-superconductor_transport.py +++ b/doc/source/tutorial/5-superconductor_transport.py @@ -13,13 +13,16 @@ import kwant from matplotlib import pyplot +#HIDDEN_BEGIN_zuuw def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4), mu=0.4, Delta=0.1, Deltapos=4, t=1.0): # Start with an empty tight-binding system and two square lattices, # corresponding to electron and hole degree of freedom lat_e = kwant.lattice.Square(a) lat_h = kwant.lattice.Square(a) +#HIDDEN_END_zuuw +#HIDDEN_BEGIN_pqmp sys = kwant.Builder() #### Define the scattering region. #### @@ -42,8 +45,10 @@ def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4), # electrons and holes sys[((lat_e(x, y), lat_h(x, y)) for x in range(Deltapos, L) for y in range(W))] = Delta +#HIDDEN_END_pqmp #### Define the leads. #### +#HIDDEN_BEGIN_ttth # left electron lead sym_lead0 = kwant.TranslationalSymmetry([lat_e.vec((-1, 0))]) lead0 = kwant.Builder(sym_lead0) @@ -61,10 +66,12 @@ def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4), # hoppings in x and y-direction lead1[lead1.possible_hoppings((1, 0), lat_h, lat_h)] = t lead1[lead1.possible_hoppings((0, 1), lat_h, lat_h)] = t +#HIDDEN_END_ttth # Then the lead to the right # this one is superconducting and thus is comprised of electrons # AND holes +#HIDDEN_BEGIN_mhiw sym_lead2 = kwant.TranslationalSymmetry([lat_e.vec((1, 0))]) lead2 = kwant.Builder(sym_lead2) @@ -76,15 +83,19 @@ def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4), lead2[lead2.possible_hoppings((1, 0), lat_h, lat_h)] = t lead2[lead2.possible_hoppings((0, 1), lat_h, lat_h)] = t lead2[((lat_e(0, j), lat_h(0, j)) for j in xrange(W))] = Delta +#HIDDEN_END_mhiw #### Attach the leads and return the system. #### +#HIDDEN_BEGIN_ozsr sys.attach_lead(lead0) sys.attach_lead(lead1) sys.attach_lead(lead2) return sys +#HIDDEN_END_ozsr +#HIDDEN_BEGIN_jbjt def plot_conductance(sys, energies): # Compute conductance data = [] @@ -94,6 +105,7 @@ def plot_conductance(sys, energies): data.append(smatrix.submatrix(0, 0).shape[0] - smatrix.transmission(0, 0) + smatrix.transmission(1, 0)) +#HIDDEN_END_jbjt pyplot.figure() pyplot.plot(energies, data) diff --git a/tutorial/README b/doc/source/tutorial/README similarity index 91% rename from tutorial/README rename to doc/source/tutorial/README index d77eef72..b7174b90 100644 --- a/tutorial/README +++ b/doc/source/tutorial/README @@ -1,6 +1,3 @@ -This directory contains the example scripts of the tutorial. - - Note for kwant developers ------------------------- diff --git a/doc/source/tutorial/tutorial1.rst b/doc/source/tutorial/tutorial1.rst index 7e02b6a8..3cbc64e2 100644 --- a/doc/source/tutorial/tutorial1.rst +++ b/doc/source/tutorial/tutorial1.rst @@ -16,8 +16,9 @@ with a hard wall confinement :math:`V(y)` in y-direction. In order to use kwant, we need to import it: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 11 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_dwhx + :end-before: #HIDDEN_END_dwhx Enabling kwant is as easy as this [#]_ ! @@ -26,15 +27,17 @@ and leads. For this we make use of the `~kwant.builder.Builder` class that allows for a convenient way to define the system. For this we need to create an instance of the `~kwant.builder.Builder` class: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 15 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_goiq + :end-before: #HIDDEN_END_goiq Apart from `~kwant.builder.Builder` we also need to specify what kind of sites we want to add to the system. Here we work with a square lattice. For simplicity, we set the lattice constant to unity: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 18-19 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_suwo + :end-before: #HIDDEN_END_suwo Since we work with a square lattice, we label the points with two integer coordinates `(i, j)`. `~kwant.builder.Builder` then @@ -51,15 +54,17 @@ needed in Builder (more about that in the technical details below). We now build a rectangular scattering region that is `W` lattice points wide and `L` lattice points long: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 21-23, 26-37 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_zfvr + :end-before: #HIDDEN_END_zfvr Next, we define the leads. Leads are also constructed using `~kwant.builder.Builder`, but in this case, the system must have a translational symmetry: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 45-46 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_xcmc + :end-before: #HIDDEN_END_xcmc Here, the `~kwant.builder.Builder` takes the translational symmetry as an optional parameter. Note that the (real space) @@ -73,8 +78,9 @@ as the hoppings inside one unit cell and to the next unit cell of the lead. For a square lattice, and a lead in y-direction the unit cell is simply a vertical line of points: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 48-54 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_ndez + :end-before: #HIDDEN_END_ndez Note that here it doesn't matter if you add the hoppings to the next or the previous unit cell -- the translational symmetry takes care of that. @@ -83,8 +89,9 @@ We also want to add a lead on the right side. The only difference to the left lead is that the vector of the translational symmetry must point to the right, the remaining code is the same: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 57-67 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_xhqc + :end-before: #HIDDEN_END_xhqc Note that here we added points with x-coordinate 0, just as for the left lead. You might object that the right lead should be placed `L` @@ -94,8 +101,9 @@ you do not need to worry about that. The `~kwant.builder.Builder` with infinitely extended. These isolated, infinite leads can then be simply attached at the right position using: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 71-72 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_fskr + :end-before: #HIDDEN_END_fskr More details about attaching leads can be found in the tutorial :ref:`tutorial-abring`. @@ -103,8 +111,9 @@ More details about attaching leads can be found in the tutorial Now we have finished building our system! We plot it, to make sure we didn't make any mistakes: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 76 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_wsgh + :end-before: #HIDDEN_END_wsgh This should bring up this picture: @@ -118,14 +127,16 @@ fading color. In order to use our system for a transport calculation, we need to finalize it -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 80 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_dngj + :end-before: #HIDDEN_END_dngj Having successfully created a system, we now can immediately start to compute its conductance as a function of energy: -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 84-95 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_buzn + :end-before: #HIDDEN_END_buzn Currently **CHANGE**, there is only one algorithm implemented to compute the conductance: :func:`kwant.solve <kwant.solvers.common.SparseSolver.solve>` @@ -138,8 +149,9 @@ Finally we can use `matplotlib` to make a plot of the computed data (although writing to file and using an external viewer such as gnuplot or xmgrace is just as viable) -.. literalinclude:: ../../../tutorial/1-quantum_wire.py - :lines: 99-105 +.. literalinclude:: 1-quantum_wire.py + :start-after: #HIDDEN_BEGIN_lliv + :end-before: #HIDDEN_END_lliv This should yield the result @@ -217,9 +229,9 @@ subbands that increases with energy. :: - fsys = sys.finalized() - del sys - sys = fsys + fsys = sys.finalized() + del sys + sys = fsys - Note that the vector passed to the `~kwant.lattice.TranslationalSymmetry` (in fact, what is passed is a list of vectors -- there could be more than @@ -267,14 +279,16 @@ We begin the program collecting all imports in the beginning of the file and put the build-up of the system into a separate function `make_system`: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 13-24 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_xkzy + :end-before: #HIDDEN_END_xkzy Previously, the scattering region was build using two ``for``-loops. Instead, we now write: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 27 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_vvjt + :end-before: #HIDDEN_END_vvjt Here, all lattice points are added at once in the first line. The construct ``((i, j) for i in xrange(L) for j in xrange(W))`` is a @@ -290,8 +304,9 @@ hoppings. In this case, an iterable like for the lattice points becomes a bit cumbersome, and we use instead another feature of kwant: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 28-29 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_nooi + :end-before: #HIDDEN_END_nooi In regular lattices, one has only very few types of different hoppings (by one lattice point in x or y-direction in the case of a square @@ -308,8 +323,9 @@ then sets all of those hopping matrix elements at once. The leads can be constructed in an analogous way: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 35-40 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_iepx + :end-before: #HIDDEN_END_iepx Note that in the previous example, we essentially used the same code for the right and the left lead, the only difference was the direction @@ -320,34 +336,39 @@ lead, but with it's translational vector reversed. This can thus be used to obtain a lead pointing in the opposite direction, i.e. makes a right lead from a left lead: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 44 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_xkdo + :end-before: #HIDDEN_END_xkdo The remainder of the code is identical to the previous example (except for a bit of reorganization into functions): -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 47-51 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_yxot + :end-before: #HIDDEN_END_yxot and -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 52-64 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_ayuk + :end-before: #HIDDEN_END_ayuk Finally, we use a python trick to make our example usable both as a script, as well as allowing it to be imported as a module. We collect all statements that should be executed in the script in a ``main()``-function: -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 67-77 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_cjel + :end-before: #HIDDEN_END_cjel Finally, we use the following python construct [#]_ that executes ``main()`` if the program is used as a script (i.e. executed as ``python tutorial1b.py``): -.. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 82-83 +.. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_ypbj + :end-before: #HIDDEN_END_ypbj If the example however is imported using ``import tutorial1b``, ``main()`` is not executed automatically. Instead, you can execute it @@ -365,8 +386,9 @@ The result of the example should be identical to the previous one. - In - .. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 28-29 + .. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_nooi + :end-before: #HIDDEN_END_nooi we write ``*hopping`` instead of ``hopping``. The reason is as follows: `~kwant.builder.Builder.possible_hoppings` expects the hopping to @@ -395,8 +417,9 @@ The result of the example should be identical to the previous one. using a tuple of sites. Hence it is worth noting a subtle detail in - .. literalinclude:: ../../../tutorial/1-quantum_wire_revisited.py - :lines: 27 + .. literalinclude:: 1-quantum_wire_revisited.py + :start-after: #HIDDEN_BEGIN_vvjt + :end-before: #HIDDEN_END_vvjt Note that ``(lat(x, y) for x in range(L) for y in range(W))`` is not a tuple, but a generator. diff --git a/doc/source/tutorial/tutorial2.rst b/doc/source/tutorial/tutorial2.rst index e0046e16..f78e0d57 100644 --- a/doc/source/tutorial/tutorial2.rst +++ b/doc/source/tutorial/tutorial2.rst @@ -37,21 +37,24 @@ In order to deal with matrices in python, kwant uses the `numpy package <numpy.scipy.org>`_. In order to use matrices in our program, we thus also have to import that package: -.. literalinclude:: ../../../tutorial/2-spin_orbit.py - :lines: 19 +.. literalinclude:: 2-spin_orbit.py + :start-after: #HIDDEN_BEGIN_xumz + :end-before: #HIDDEN_END_xumz For convenience, we define the Pauli-matrices first (with `sigma_0` the unit matrix): -.. literalinclude:: ../../../tutorial/2-spin_orbit.py - :lines: 22-25 +.. literalinclude:: 2-spin_orbit.py + :start-after: #HIDDEN_BEGIN_hwbt + :end-before: #HIDDEN_END_hwbt Previously, we used numbers as the values of our matrix elements. However, `~kwant.builder.Builder` also accepts matrices as values, and we can simply write: -.. literalinclude:: ../../../tutorial/2-spin_orbit.py - :lines: 36-43 +.. literalinclude:: 2-spin_orbit.py + :start-after: #HIDDEN_BEGIN_uxrm + :end-before: #HIDDEN_END_uxrm Note that the Zeeman energy adds to the onsite term, whereas the Rashba spin-orbit term adds to the hoppings (due to the derivative operator). @@ -78,8 +81,9 @@ when specifying `(1, 0)` it is not necessary to specify `(-1, 0)`), The leads also allow for a matrix structure, -.. literalinclude:: ../../../tutorial/2-spin_orbit.py - :lines: 50-56 +.. literalinclude:: 2-spin_orbit.py + :start-after: #HIDDEN_BEGIN_yliu + :end-before: #HIDDEN_END_yliu The remainder of the code is unchanged, and as a result we should obtain the following, clearly non-monotonic conductance steps: @@ -124,8 +128,9 @@ changing the potential then implies the need to build up the system again. Instead, we use a python *function* to define the onsite energies. We define the potential profile of a quantum well as: -.. literalinclude:: ../../../tutorial/2-quantum_well.py - :lines: 16-18, 21-24, 27-33 +.. literalinclude:: 2-quantum_well.py + :start-after: #HIDDEN_BEGIN_ehso + :end-before: #HIDDEN_END_ehso This function takes one argument which is of type `~kwant.builder.Site`, from which you can get the realspace @@ -140,8 +145,9 @@ the transmission as a function of well depth. kwant now allows us to pass a function as a value to `~kwant.builder.Builder`: -.. literalinclude:: ../../../tutorial/2-quantum_well.py - :lines: 35-40 +.. literalinclude:: 2-quantum_well.py + :start-after: #HIDDEN_BEGIN_coid + :end-before: #HIDDEN_END_coid For each lattice point, the corresponding site is then passed to the function `onsite()`. Note that we had to define `onsite()`, as it is @@ -155,8 +161,9 @@ of the lead -- this should be kept in mind. Finally, we compute the transmission probability: -.. literalinclude:: ../../../tutorial/2-quantum_well.py - :lines: 67, 70-82 +.. literalinclude:: 2-quantum_well.py + :start-after: #HIDDEN_BEGIN_sqvr + :end-before: #HIDDEN_END_sqvr Since we change the value of the global variable `pot` to vary the well depth, python requires us to write ``global pot`` to `enable @@ -185,10 +192,9 @@ oscillatory transmission behavior through resonances in the quantum well. - Functions can also be used for hoppings. In this case, they take two `~kwant.builder.Site`'s as arguments. - - In tutorial/2-quantum_well.py, line 16 + - In tutorial/2-quantum_well.py, the line :: - .. literalinclude:: ../../../tutorial/2-quantum_well.py - :lines: 16 + pot = 0 is not really necessary. If this line was left out, the global variable `pot` would in fact be created by the @@ -290,8 +296,9 @@ First, define a boolean function defining the desired shape, i.e. a function that returns ``True`` whenever a point is inside the shape, and ``False`` otherwise: -.. literalinclude:: ../../../tutorial/2-ab_ring.py - :lines: 21, 24-27, 31-34 +.. literalinclude:: 2-ab_ring.py + :start-after: #HIDDEN_BEGIN_eusz + :end-before: #HIDDEN_END_eusz Note that this function takes a realspace position as argument (not a `~kwant.builder.Site`). @@ -300,8 +307,9 @@ We can now simply add all of the lattice points inside this shape at once, using the function `~kwant.lattice.Square.shape` provided by the lattice: -.. literalinclude:: ../../../tutorial/2-ab_ring.py - :lines: 37-39 +.. literalinclude:: 2-ab_ring.py + :start-after: #HIDDEN_BEGIN_lcak + :end-before: #HIDDEN_END_lcak Here, ``lat.shape()`` takes as a second parameter a (realspace) point that is inside the desired shape. The hoppings can still be added @@ -314,8 +322,9 @@ along the branch cut in the lower arm of the ring. For this we select all hoppings in x-direction that are of the form `(lat(1, j), lat(0, j))` with ``j<0``: -.. literalinclude:: ../../../tutorial/2-ab_ring.py - :lines: 47-59 +.. literalinclude:: 2-ab_ring.py + :start-after: #HIDDEN_BEGIN_lvkt + :end-before: #HIDDEN_END_lvkt Here, `crosses_branchcut` is a boolean function that returns ``True`` for the desired hoppings. We then use again a generator (this time with @@ -328,16 +337,18 @@ by the global variable `phi`. For the leads, we can also use the ``lat.shape()``-functionality: -.. literalinclude:: ../../../tutorial/2-ab_ring.py - :lines: 63-72 +.. literalinclude:: 2-ab_ring.py + :start-after: #HIDDEN_BEGIN_qwgr + :end-before: #HIDDEN_END_qwgr Here, the shape must cover *at least* one unit cell of the lead (it does not hurt if it covers more unit cells). Attaching the leads is done as before: -.. literalinclude:: ../../../tutorial/2-ab_ring.py - :lines: 79-80 +.. literalinclude:: 2-ab_ring.py + :start-after: #HIDDEN_BEGIN_skbz + :end-before: #HIDDEN_END_skbz In fact, attaching leads seems not so simple any more for the current structure with a scattering region very much different from the lead diff --git a/doc/source/tutorial/tutorial3.rst b/doc/source/tutorial/tutorial3.rst index 5907ff94..ac334262 100644 --- a/doc/source/tutorial/tutorial3.rst +++ b/doc/source/tutorial/tutorial3.rst @@ -15,8 +15,9 @@ tight-binding wire. Computing band structures in kwant is easy. Just define a lead in the usual way: -.. literalinclude:: ../../../tutorial/3-band_structure.py - :lines: 17-34 +.. literalinclude:: 3-band_structure.py + :start-after: #HIDDEN_BEGIN_zxip + :end-before: #HIDDEN_END_zxip "Usual way" means defining a translational symmetry vector, as well as one unit cell of the lead, and the hoppings to neighboring @@ -30,8 +31,9 @@ that allows to compute the eigenenergies of the translational invariant system for a given momentum `k`. Computing these eigenenergies for different momenta `k` then yields the bandstructure: -.. literalinclude:: ../../../tutorial/3-band_structure.py - :lines: 37 - 55 +.. literalinclude:: 3-band_structure.py + :start-after: #HIDDEN_BEGIN_pejz + :end-before: #HIDDEN_END_pejz This gives the result: @@ -75,14 +77,16 @@ circular quantum dot as a function of magnetic field To compute the eigenenergies, we will make use of the linear algebra functionality of `scipy <www.scipy.org>`_: -.. literalinclude:: ../../../tutorial/3-closed_system.py - :lines: 16 +.. literalinclude:: 3-closed_system.py + :start-after: #HIDDEN_BEGIN_tibv + :end-before: #HIDDEN_END_tibv We set up the system using the `shape`-function as in :ref:`tutorial-abring`, but do not add any leads: -.. literalinclude:: ../../../tutorial/3-closed_system.py - :lines: 26-48 +.. literalinclude:: 3-closed_system.py + :start-after: #HIDDEN_BEGIN_qlyd + :end-before: #HIDDEN_END_qlyd We add the magnetic field using a function and a global variable as we did in the two previous tutorial. (Here, the gauge is chosen such that @@ -92,8 +96,9 @@ The spectrum can be obtained by diagonalizing the Hamiltonian of the system, which in turn can be obtained from the finalized system using `~kwant.system.System.hamiltonian_submatrix`: -.. literalinclude:: ../../../tutorial/3-closed_system.py - :lines: 51, 53, 60-76 +.. literalinclude:: 3-closed_system.py + :start-after: #HIDDEN_BEGIN_yvri + :end-before: #HIDDEN_END_yvri In this toy model we use dense matrices and dense matrix algebra since the system is very small. (In a real application one would probably diff --git a/doc/source/tutorial/tutorial4.rst b/doc/source/tutorial/tutorial4.rst index a93e4ae4..4d9eb5f4 100644 --- a/doc/source/tutorial/tutorial4.rst +++ b/doc/source/tutorial/tutorial4.rst @@ -14,8 +14,9 @@ We begin by defining the honeycomb lattice of graphene. This is in principle already done in `kwant.lattice.Honeycomb`, but we do it explicitly here to show how to define a new lattice: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 24-27 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_hnla + :end-before: #HIDDEN_END_hnla The first argument to the `~kwant.lattice.make_lattice` function is the list of primitive vectors of the lattice; the second one is the coordinates of basis @@ -26,8 +27,9 @@ itself forms a regular lattice of the same type as well, and those In the next step we define the shape of the scattering region (circle again) and add all lattice points using the ``shape()``-functionality: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 29-30, 33-38, 40-45 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_shzy + :end-before: #HIDDEN_END_shzy As you can see, this works exactly the same for any kind of lattice. We add the onsite energies using a function describing the p-n junction; @@ -40,8 +42,9 @@ As a next step we add the hoppings, making use of lattice (instead of `kwant.lattice.Honeycomb`), we have to define the hoppings ourselves: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 49 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_hsmc + :end-before: #HIDDEN_END_hsmc The nearest-neighbor model for graphene contains only hoppings between different basis atoms. For these type of @@ -57,24 +60,27 @@ respect to the two primitive vectors ``[(1, 0), (sin_30, cos_30)]``. Adding the hoppings however still works the same way: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 50-51 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_bfwb + :end-before: #HIDDEN_END_bfwb Modifying the scattering region is also possible as before. Let's do something crazy, and remove an atom in sublattice A (which removes also the hoppings from/to this site) as well as add an additional link: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 54-55 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_efut + :end-before: #HIDDEN_END_efut Note again that the conversion from a tuple `(i,j)` to site is done by the sublattices `a` and `b`. The leads are defined as before: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 58-82 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_aakh + :end-before: #HIDDEN_END_aakh Note that the translational vectors ``graphene.vec((-1, 0))`` and ``graphene.vec((0, 1))`` are *not* orthogonal any more as they would have been @@ -85,14 +91,16 @@ Later, we will compute some eigenvalues of the closed scattering region without leads. This is why we postpone attaching the leads to the system. Instead, we return the scattering region and the leads separately. -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 84 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_kmmw + :end-before: #HIDDEN_END_kmmw The computation of some eigenvalues of the closed system is done in the following piece of code: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 87-91, 95-98 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_zydk + :end-before: #HIDDEN_END_zydk Here we use in contrast to the previous example a sparse matrix and the sparse linear algebra functionality of scipy (this requires @@ -106,16 +114,19 @@ to the previous examples, and needs not be further explained here. Finally, in the `main()` function we make and plot the system: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 127-130, 139 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_itkk + :end-before: #HIDDEN_END_itkk We customize the plotting: `plotter_symbols` is a dictionary with the sublattice objects `a` and `b` as keys, and the `~kwant.plotter.Circle` objects specify that the sublattice `a` should be drawn using a filled black circle, -and `b` using a white circle with a black outline. +and `b` using a white circle with a black outline. :: -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 133-136 + plotter_symbols = {a: kwant.plotter.Circle(r=0.3), + b: kwant.plotter.Circle(r=0.3, + fcol=kwant.plotter.white, + lcol=kwant.plotter.black)} The radius of the circle is given in relative units: `~kwant.plotter.plot` uses a typical length scale as a reference length. By default, the typical length @@ -135,8 +146,9 @@ Plotting the closed system gives this result: Computing the eigenvalues of largest magnitude, -.. literalinclude:: ../../../tutorial/4-graphene.py - :lines: 142 +.. literalinclude:: 4-graphene.py + :start-after: #HIDDEN_BEGIN_jmbi + :end-before: #HIDDEN_END_jmbi should yield two eigenvalues similar to `[ 3.07869311 +1.02714523e-17j, -3.06233144 -6.68085759e-18j]` (round-off might change the imaginary part which diff --git a/doc/source/tutorial/tutorial5.rst b/doc/source/tutorial/tutorial5.rst index 3617286f..a7dbbbfb 100644 --- a/doc/source/tutorial/tutorial5.rst +++ b/doc/source/tutorial/tutorial5.rst @@ -28,8 +28,9 @@ We begin by computing the band structure of a superconducting wire. The most natural way to implement the BdG Hamiltonian is by using a 2x2 matrix structure for all Hamiltonian matrix elements: -.. literalinclude:: ../../../tutorial/5-superconductor_band_structure.py - :lines: 21-42 +.. literalinclude:: 5-superconductor_band_structure.py + :start-after: #HIDDEN_BEGIN_nbvn + :end-before: #HIDDEN_END_nbvn As you see, the example is syntactically equivalent to our :ref:`spin example <tutorial_spinorbit>`, the only difference @@ -80,8 +81,9 @@ a superconductor on the right, and a tunnel barrier inbetween: As already mentioned above, we begin by introducing two different square lattices representing electron and hole degrees of freedom: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 16-17,15,20-21 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_zuuw + :end-before: #HIDDEN_END_zuuw Any diagonal entry (kinetic energy, potentials, ...) in the BdG Hamiltonian then corresponds to on-site energies or hoppings within @@ -89,8 +91,9 @@ the *same* lattice, whereas any off-diagonal entry (essentially, the superconducting order parameter :math:`\Delta`) corresponds to a hopping between *different* lattices: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 23-44 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_pqmp + :end-before: #HIDDEN_END_pqmp Note that the tunnel barrier is added by overwriting previously set on-site matrix elements. @@ -103,8 +106,9 @@ part. We use this fact to attach purely electron and hole leads (comprised of only electron *or* hole lattices) to the system: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 47-63 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_ttth + :end-before: #HIDDEN_END_ttth This separation into two different leads allows us then later to compute the reflection probablities between electrons and holes explicitely. @@ -112,15 +116,17 @@ reflection probablities between electrons and holes explicitely. On the superconducting side, we cannot do this separation, and can only define a single lead coupling electrons and holes: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 68-78 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_mhiw + :end-before: #HIDDEN_END_mhiw We now have on the left side two leads that are sitting in the same spatial position, but in different lattice spaces. This ensures that we can still attach all leads as before: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 81-85 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_ozsr + :end-before: #HIDDEN_END_ozsr When computing the conductance, we can now extract reflection from electrons to electrons as ``smatrix.transmission(0, 0)`` (Don't get @@ -128,8 +134,9 @@ confused by the fact that it says ``transmission`` -- transmission into the same lead is reflection), and reflection from electrons to holes as ``smatrix.transmission(1, 0)``, by virtue of our electron and hole leads: -.. literalinclude:: ../../../tutorial/5-superconductor_transport.py - :lines: 88-96 +.. literalinclude:: 5-superconductor_transport.py + :start-after: #HIDDEN_BEGIN_jbjt + :end-before: #HIDDEN_END_jbjt Note that ``smatrix.submatrix(0,0)`` returns the block concerning reflection within (electron) lead 0, and from its size we can extract the number of modes diff --git a/setup.py b/setup.py index ef029c03..e1a5f2dc 100755 --- a/setup.py +++ b/setup.py @@ -5,14 +5,19 @@ STATIC_VERSION_FILE = 'kwant/_static_version.py' REQUIRED_CYTHON_VERSION = (0, 17, 1) MUMPS_DEBIAN_PACKAGE = 'libmumps-scotch-dev' NO_CYTHON_OPTION = '--no-cython' +TUT_DIR = 'tutorial' +TUT_GLOB = 'doc/source/tutorial/*.py' +TUT_HIDDEN_PREFIX = '#HIDDEN' import sys import os +import glob import subprocess import ConfigParser -from distutils.core import setup +from distutils.core import setup, Command from distutils.extension import Extension from distutils.errors import DistutilsError, CCompilerError +from distutils.command.build import build as distutils_build import numpy try: @@ -54,6 +59,36 @@ Build configuration was: print build_summary +class build_tut(Command): + description = "build the tutorial scripts" + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if not os.path.exists(TUT_DIR): + os.mkdir(TUT_DIR) + for in_fname in glob.glob(TUT_GLOB): + out_fname = os.path.join(TUT_DIR, os.path.basename(in_fname)) + with open(in_fname) as in_file, open(out_fname, 'w') as out_file: + for line in in_file: + if not line.startswith(TUT_HIDDEN_PREFIX): + out_file.write(line) + + +# Our version of the "build" command also makes sure the tutorial is made. +# Even though the tutorial is not necessary for installation, and "build" is +# supposed to make everything needed to install, this is a robust way to ensure +# that the tutorial is present. +class kwant_build(distutils_build): + sub_commands = [('build_tut', None)] + distutils_build.sub_commands + pass + + # This is an exact copy of the function from kwant/version.py. We can't import # it here (because kwant is not yet built when this scipt is run), so we just # include a copy. @@ -279,7 +314,9 @@ def main(): license="not to be distributed", packages=["kwant", "kwant.graph", "kwant.linalg", "kwant.physics", "kwant.solvers"], - cmdclass={'build_ext': kwant_build_ext}, + cmdclass={'build': kwant_build, + 'build_ext': kwant_build_ext, + 'build_tut': build_tut}, ext_modules=ext_modules(extensions()), include_dirs=[numpy.get_include()]) -- GitLab