Commit 8e0a0a1c authored by Joseph Weston's avatar Joseph Weston
Browse files

Merge branch 'api-design'

See !16
parents 489b0e4b 1d0cdd39
Pipeline #14109 passed with stage
in 2 minutes
semicon/_static_version.py export-subst
\ No newline at end of file
......@@ -105,3 +105,4 @@ ENV/
# this project
kp_models/cache.json
.pytest_cache
semicon/model_cache.json
image: kwant/testing
stages:
- build
- test
build package:
stage: build
test package:
stage: test
script:
- python3 setup.py build
- pip3 install sympy==1.1.1
- pip3 install -e .
- py.test -r w --cov semicon --cov-report term --flakes semicon
test package:
test package with latest scipy:
stage: test
script:
- pip3 install sympy==1.1.1 scipy==1.2.0rc2
- pip3 install -e .
- py.test -r w --cov semicon --cov-report term --flakes semicon
test package with latest SymPy and Kwant stable:
stage: test
script:
- pip3 install sympy
- pip3 install git+https://gitlab.kwant-project.org/kwant/kwant.git@stable
- pip3 install -e .
- py.test -r w --cov semicon --cov-report term --flakes semicon
test packaging:
stage: test
script:
- pip3 install sympy==1.1.1
- pip3 install .
- cd / # make sure we don't import the cloned version
- python3 -c 'import semicon; semicon.test()'
include LICENSE README.md
include semicon/databank/*.yml
This source diff could not be displayed because it is too large. You can view the blob instead.
%% Cell type:markdown id: tags:
# basic interface idea (prototype)
# Idea of API
See corresponding [issue](https://gitlab.kwant-project.org/semicon/semicon/issues/16).
%% Cell type:markdown id: tags:
## Basic idea
%% Cell type:code id: tags:
``` python
import semicon
from semicon.models import ZincBlende
from semicon.helpers import interpolate_parameters
bands = ['gamma_6c', 'gamma_8v', 'gamma_7v']
# this will be probably a sympy model, that
# can directly be used by ``kwant.continuum.discretizer``.
# coords describe space dependence of parameters
# bands and components are sequence of strings
model = ZincBlende(coords='z', bands=..., components=...)
# hamiltonian property returned as sympy object
smp_ham = model.hamiltonian
# parameters returned via method of model
# this method has access to "bands" and "components" and return
# a parameter class object: subclass of dict with extra method
# for removing spurious solutions
pInAs = model.parameters(material='InAs', databank=lawaetz)
pInAs = pInAs.renormalize(gamma_0=1)
hamiltonian = semicon.models.kane(
components=['base', 'zeeman', 'dresselhaus'],
bands=bands,
coords='z',
)
# this will be a dictionary that can be passed into ``params`` of kwant system.
# possible it will also have attributes with extra information about material
# sources, etc.
parameters = semicon.parameters.two_deg(
bank='lawaetz',
materials=['AlSb', 'InAs', 'GaSb', 'InAs'],
widths=[5, 12.5, 5, 5],
valence_band_offsets=[.18, .0, .56, .18]
extra_constants={'hbar': 1, 'e': 1},
bands=bands,
# these could be for example combined with helper function
# to provide interpolated smooth functions for a "sandwich"
# two-deg system
parameters = {k: model.parameters(material=k).renormalize(gamma_0=1)
for k in ['InAs', 'GaSb', 'AlSb']}
syst = ... # user defines his system of appropriate shape and fill
# with smp_ham through discretizer on his own
# assingment is mapping from coords to material name
parameters = interpolate_parameters(syst, parameters, assingment)
```
%% Cell type:markdown id: tags:
## basic bulk example
%% Cell type:code id: tags:
``` python
from semicon.models import ZincBlende
model = ZincBlende(
bands=('gamma_6c', 'gamma_8v', 'gamma_7v'),
components=('base', 'zeeman', 'strain'),
)
params = model.parameters(material='InAs').renormalize(gamma_0=1)
# and standard kwant code (for continuum disp)
disp = kwant.continuum.lambdify(model.hamiltonian)
e_k = lambda kx, ky, kz: disp(k_x=kx, k_y=ky, k_z=kz, **params)
...
shape = semicon.shapes.two_deg(L=sum(parameters.widths))
# and standard kwant code (for tb dispersion)
template = kwant.continuum.discretize(model.hamiltonian, grid_spacing=0.5)
syst = kwant.wraparound.wraparound(template).finalized()
e_k = lambda kx, ky, kz: syst.hamiltonian_submpatrix(params=dict('k_x': k_x, ..., **params))
...
```
%% Cell type:markdown id: tags:
## basic two-deg example
%% Cell type:code id: tags:
``` python
import kwant
template = kwant.continuum.discretize(hamiltonian, coords='z', grid_spacing=0.5)
from semicon.models import ZincBlende
import semicon
model = ZincBlende(
coords='z',
bands=('gamma_6c', 'gamma_8v', 'gamma_7v'),
components=('base', 'zeeman', 'strain'),
)
parameters = {k: model.parameters(material=k).renormalize(gamma_0=1)
for k in ['InAs', 'GaSb', 'AlSb']}
```
%% Cell type:markdown id: tags:
### get system
%% Cell type:code id: tags:
``` python
grid = 0.5
L = 20
template = kwant.continuum.discretize(model.hamiltonian, coords='z', grid_spacing=a)
syst = kwant.Builder()
shape = semicon.shapes.twodeg(start=0 - a/2, end=L + a/2)
syst.fill(template, shape, (0,))
syst = syst.finalized()
```
%% Cell type:markdown id: tags:
## get 2deg parameters
%% Cell type:code id: tags:
``` python
def twodeg_mapping(z):
"""User specified mapping from coord to material."""
return 'AlSb' if z < 5 or z > 5 else 'InAs'
pars_2deg = semicon.helpers.interpolate(
syst=syst,
parameters=parameters,
mapping=twodeg_mapping
)
```
%% Cell type:markdown id: tags:
## and finally obtain hamiltonian and do simulation
%% Cell type:code id: tags:
``` python
ham = syst.hamiltonian_submatrix(params=pars_2deg)
...
```
%% Cell type:markdown id: tags:
# further nice helpers
%% Cell type:markdown id: tags:
## different growth direction
Basic idea about the rotation of coordinates is explained in this [notebook](./rotations.ipynb) and discussed in this [issue](https://gitlab.kwant-project.org/semicon/semicon/issues/12).
From the notebook it is clear that applying rotation produce ugly numerical coefficients in the Hamiltonian. Therefore it may be good idea to chain this method with ``prettify`` functionality.
%% Cell type:code id: tags:
``` python
from semicon.models import ZincBlende
model = ZincBlende(
bands=('gamma_6c', 'gamma_8v', 'gamma_7v'),
components=('base', 'zeeman', 'strain'),
)
R = ... # 3x3 rotation matrix
model = model.rotate(R, act_on=semicon.symbols.momenta) \
.prettify(zero_atol=1e-8, nsimplify=True)
ham = syst.hamiltonian_submatrix(params=parameters)
# note: Using "act_on" to specify rotation of only momenta
# allows to leave coords unchanged (treat them as they
# would be already defined in simulation coordinate system)
```
......
%% Cell type:code id: tags:
``` python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
```
%% Cell type:code id: tags:
``` python
def interpolate(point, values, coords):
diffs = np.abs(coords - point)
weights = np.prod(1 - diffs, axis = 1)
return weights @ values
```
%% Cell type:code id: tags:
``` python
values = np.array([0, 0, 0, 1])
points = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
xs = np.linspace(0, 1, 100)
plt.imshow([[interpolate(np.array([x, y]), values, points)
for x in xs]
for y in xs])
```
%% Output
<matplotlib.image.AxesImage at 0x7f8fdc189588>
This diff is collapsed.