[ Home ] [ News ] [ Contact ] [ Search ]

 ==> Download Software
 nextnano³ documentation

 Copyright notice
 About us
 Useful Links
 Publications
 
 * password protected

 

 
 

Grids and Geometry

1. Grids

1.1 Material grid

1.2 Physical grid

1.3 Stefan's grid (Multiple grid points)
    1.3.1    3D
    1.3.2    2D
    1.3.3    1D

2. Quantum regions

3. Structure functions (Grid mapping)
    3.1    3D
    3.2    2D
    3.3    1D

4. Rotations
    4.1    1D Simulation
    4.2    2D Simulation
    4.3    3D Simulation

 

1. Grids

Note: The way the grid is processed via the input file was changed. In the original setup, the coordinates in the input file determined the material grid points as described below and resulting from this definition, the physical grid points were defined accordingly. Now it is the opposite way. In the input file, the input file determines the physical grid points and material grid points are defined with respect to this new definiton. You can ask Matthias Sabathil for more details. The description and the pictures below are not applicable any more, in principle, but still helpful.
New:
- Number of physical grid points as specified in input file: nx, ny, nz
- Number of material grid points: nx-1, ny-1, nz-1
At the simulation boundaries, only physical grid points are defined.
The material grid points correspond to a volume grid.
The physical grid corresponds to the grid lines and nodes as specified in the input file.

Old:
- Number of material grid points as specified in input file: N
- Number of physical grid points: N+1
At the simulation boundaries, both physical and material grid points are defined.

1.1 Material grid (volume grid)

The Input Parser creates a rectangular mesh with varying grid size. For each mesh point information about material data can be obtained. This grid supplied by the Input System will be called material grid in the following.

Fig. 1: Material grid: Rectangular mesh with varying grid size.

The main characteristics of the material grid can be obtained via MODULE define_geometry:
The mesh points are (irrespective of dimension 1D/2D/3D) numbered from  1  to n_material_points, and each mesh point contains a material number in material_gridV which is the number of the cluster (specified in the Input File) which this point belongs to.

In order to transform the point number (1 to n_material_points) to grid coordinates (i,j,k) in 3D for the x-, y- and z-axis [respectively (i,j) in 2D for the x- and y-axis] one can use the functions subroutine i_j_k_to_ijk, subroutine ijk_to_i_j_k and subroutine material_coordinates in MODULE input_block_one.

 --> x(1), x(2), x(3), x(4), ...
 --> y(1), y(2), y(3), y(4), ...
 --> z(1), z(2), z(3), z(4), ...

The subroutine material_coordinates provides the coordinates (x,y,z) of the corresponding mesh point on the material grid.

material_coordinates(i) -> x(i), y(i), z(i)

For 2D and 1D the same applies.

Note that in 1D subroutine i_j_k_to_ijk and subroutine ijk_to_i_j_k do not make sense and so they do not exist at all.

 

1.2 Physical grid

The grid on which physical calculations are done, is derived from the material grid by the following convention:

All grid points are placed in the middle (of the cell) between material grid points. This is called the physical grid in the following. Thus the number of x nodes of the physical grid is equal to the number of x nodes of material grid plus 1. (Be aware, that if a material grid point lies at the corner (or at the left or right side in 1D), a physical grid point is placed there as well. For details, see picture below.)



2D example (see picture further below):

    
Material grid points and corresponding physical grid point:

y
^
 |
 |                           
o                                                        o
 |                       
(x1,y2)                                                (x2,y2)
 |
 |                                                          o
 |                                         
( (x1+x2)/2 , (y1+y2)/2) )
 |
 |                           
o                                                        o
 |                       
(x1,y1)                                                 (x2,y1)
 |
---------------------------------------------------->  x

For boundaries, the physical grid points are lying directly between 2 of the material grid points.

                            o                              o                                  o
                       
(x1,y20)             ( (x1+x2)/2 , y20 )                 (x2,y20)
 

For material grid points lying at the vertexes (~corners), the physical grid points are identical to material grid points.

                            o / o
                   
(x1,y1) / (x1,y1)
 

So each mesh point on the physical grid contains in each octant exactly one of material grid points (in 3D!). We will call them octants also for 2D and 1D in the following although there are only 4 and 2 neighboring points, respectively.
Definition of interfaces:
The mesh points of the physical grid are placed exactly on interfaces between different
materials.
(In old versions it held: Actually, the interfaces are defined by this definition and not by the input file.)
(In new versions it holds: Actually, the interfaces are defined by the input file.)

The whole information about the grid is stored in MODULE gitter:

For a mesh point (i,j,k) on the physical grid it holds:
  i=1,...,
n_1 , j=1,...,n_2 , k=1,...,n_3
       in 3D.
[ i=1,...,n_1 , j=1,...,n_2                  in 2D and
  i=1,...,n_1                                                 in 1D].

The distance between the points is stored in h_1V(1...n_1-1), h_2V(1...n_2-1) and h_3D(1...n_3-1) in meter [m].
(x_0,y_0,z_0) is the absolute position of point (i=1,j=1,k=1) in [m].
As pointed out before, the whole device is decomposed into material regions with different material numbers.
The variable num_materials in MODULE gitter contains the number of different kinds of materials specified.
All these variables are allocated and defined in subroutine generate_mesh3D [generate_mesh2D, generate_mesh1D].

 

1.3 Stefan's grid (=physical grid plus multiple points)

In order to be able to handle discontinuous quantities at interfaces (e.g. densities), one has to introduce multiple points at interfaces. These multiple points have the same geometric coordinates and they describe the physical quantity in dependence of the direction from which one approaches the interface.

Attention: Multiple points have different letters in different dimensions!
        1D: punktartCV =       ! doesn't exist
        2D: punktartCV = 'v'   !
is called 'v' (German vier = 4 = four)
        3D: punktartCV = 'a'   !
is called 'a' (German acht = 8 = eight)

 

1.3.1 In 3D this is done as follows:

The program loops through all points of the physical grid and gets the eight adjoining points on the material grid as well as their material number.
The eight adjoining points on the material grid are stored in adjoining_coord3DM(n_1,n_2,n_3,1:8) = (i_j_k1,...,i_j_k8)
[numbering  (i-,j-,k-)
         (i+,j-,k-)
         (i-,j+,k-)
         (i+,j+,k-)
         (i-,j-,k+)
         (i+,j-,k+)
         (i-,j+,k+)
         (i+,j+,k+)
]

In case the material numbers are not identical, a multiple point is defined. The multiple points are numbered from 1 to num_mult_points. It holds:
  (i,j,k) a single point    <==> PointInfoM(i,j,k) = 0
  (i,j,k) a multiple point <==> PointInfoM(i,j,k) contains the number of the multiple point
                           (1..num_mult_points).

The multiple points are further characterized in punktartCV(1..num_mult_points):

  • Interface perpendicular to x-axis:    punktartCV = '|' ,
    i.e.
    a double point is set [numbering (i-,j,k) , (i+,j,k) ]
  • Interface perpendicular to y-axis:    punktartCV = '-' ,
    i.e. a double point is set [numbering (i,j-,k) , (i,j+,k) ]
  • Interface perpendicular to z-axis:    punktartCV = '/' ,
    i.e. a double point is set [numbering (i,j,k-) , (i,j,k+) ]
  • All other cases:                             punktartCV = 'a' ,
    i.e. an eightfold point is assumed ('a' comes from the German word "acht"=eight).

    [numbering  (i-,j-,k-)
             (i+,j-,k-)
             (i-,j+,k-)
             (i+,j+,k-)
             (i-,j-,k+)
             (i+,j-,k+)
             (i-,j+,k+)
             (i+,j+,k+)
    ]

The grid which additionally comprises multiple points is called Stefan's grid in the following.
All mesh points on Stefan's grid are numbered from  1  to lengvecV.

The mapping from physical grid to Stefan's grid and vice versa is done via addressM and phys_gridM:

  • addressM(i,j,k)
    contains the position of the point (i,j,k) - or in case of a multiple point the position of the first of them -
    on Stefan's grid, so:
    if (i,j,k) is an eightfold point, the position for the eight octants are contained in
    [addressM(i,j,k),...,addressM(i,j,k)+7]
  • phys_gridM(1..lengvecV,1..3)
    is the inverse operation: it contains for each point on Stefan's grid the position on the
    physical grid, i.e.

       phys_gridM(addressM(i,j,k),1) = i
       phys_gridM(addressM(i,j,k),2) = j
       phys_gridM(addressM(i,j,k),3) = k

In order to obtain the coordinates of multiple points, one can use
   coord_mult_points3DM(1:num_mult_points,3):

   coord_mult_pointsM(n,1:3) = (i,j,k) of nth multiple point on physical grid.

Because material numbers are used very often they are also stored on Stefan's grid in mat_numberV.

All these variables are allocated and defined in subroutine generate_multiple_points3D.

 

1.3.2 In 2D the situation is analogous:

The program loops through all points of the physical grid and gets the four adjoining points on material grid as well as their material number.
The four adjoining points on the material grid are stored in adjoining_coord2DM(n_1,n_2,1:4) = (i_j_k1,...,i_j_k4)
[numbering (i-,j-),(i+,j-),(i-,j+),(i+,j+)]
In case the material numbers are not identical, a multiple point is defined. The multiple points are numbered from  1  to num_mult_points. It holds:
  (i,j) a single point    <==>  PointInfoM(i,j,k=1) =0
  (i,j) a multiple point <==>  PointInfoM(i,j,k=1) contains the number of the multiple point (1..num_mult_points).

The multiple points are further characterized in punktartCV(1..num_mult_points):

  • Interface perpendicular to x-axis:     punktartCV = '|' ,
    i.e. a double point is set                   [numbering (i-,j), (i+,j ]
  • Interface perpendicular to y-axis:     punktartCV = '-' ,
    i.e. a double point is set                   [numbering (i,j-), (i,j+)]
  • All other cases:                 punktartCV = 'v' ,
    i.e. a fourfold point is assumed         [numbering (i-,j-),(i+,j-),(i-,j+),(i+,j+)]
    ('v' comes from the German word "vier"=four)

The grid which additionally comprises multiple points is called Stefan's grid in the following.
All mesh points on Stefan's grid are numbered from  1  to lengvecV.
The mapping from physical grid to Stefan's grid and vice versa is done via addressM and phys_gridM:

  • addressM(i,j,k=1)
    contains the position of the point (i,j) - or in case of a multiple point the position of the first of them -
    on Stefan's grid, so:
    if (i,j) is an fourfold point, the position for the four "octants" are contained in [addressM(i,j,k=1),...,addressM(i,j,k=1)+3]
  • phys_gridM(1..lengvecV,1..2)
    is the inverse operation: it contains for each point on Stefan's grid the position on the
    physical grid, i.e.

       phys_gridM(addressM(i,j,k=1),1) = i

       phys_gridM(addressM(i,j,k=1),2) = j

In order to obtain the coordinates of multiple points, one can use
   coord_mult_points2DM(1:num_mult_points,2):
   coord_mult_pointsM(n,1:2) = (i,j) of nth multiple point on physical grid.

Because material numbers are used very often they are also stored on Stefan's grid in mat_numberV.

All these variables are allocated and defined in subroutine generate_multiple_points2D.

 

1.3.3 In 1D the situation is analogous:

The program loops through all points of the physical grid and gets the two adjoining points on material grid as well as their material number.
In case the material numbers are not identical, a multiple point is defined. The multiple points are numbered from 1 to num_mult_points. It holds:
 (i) a single point     <==> 
PointInfoM(i,j=1,k=1) = 0
 (i) a multiple point   <==> 
PointInfoM(i,j=1,k=1) contains the number of the double point (1..num_mult_points).
The grid which additionally comprises multiple points is called Stefan's grid in the following.
All mesh points on Stefan's grid are numbered from  1  to lengvecV.
The mapping from physical grid to Stefan's grid and vice versa is done via addressM and phys_gridM:

  • addressM(i,j=1,k=1)
    contains the position of the point (i) - or in case of a multiple point the position of the first of them - on Stefan's grid, so:

    if (i) is a double point, the position for the two "octants" are contained in [addressM(i,j=1,k=1),...,addressM(i,j=1,k=1)+1]
  • phys_gridM(1..lengvecV,1)
    is the inverse operation: it contains for each point on Stefan's grid the position on the
    physical grid, i.e.

       phys_gridM(addressM(i,j=1,k=1),1) = i

In order to obtain the coordinates of multiple points, one can use
   coord_mult_points1DV(1:num_mult_points,1):

   coord_mult_points1DV(n,1) = (i) of nth multiple point on physical grid.

Because material numbers are used very often they are also stored on Stefan's grid in mat_numberV.

All these variables are allocated and defined in subroutine generate_multiple_points1D.

 

 

2. Quantumregions

Quantum regions are specified independently from material regions. Therefore they must be separately stored in an additional vector.
The input system provides information about quantumregions in MODULE define_geometry:

  • iquantumregions  ...   number of quantum regions
  • quantum_guentherV (1..n_material_points) ... contains for each point on material grid which quantum region it belongs to,
    = 0 , if it does not belong to any

In subroutine setup_quantumregion these quantum regions are projected on the physical grid by the following convention:

For each point on the physical grid the adjoining point on the material grid with the highest quantum region number defines which quantum region this point belongs to.
In each quantum region n, the points are numbered from 1 to dim_qrV(n), so dim_qrV(1..num_qr_regions) contains for each quantum region the dimension (num_qr_regions is the number of quantum regions).

The point number within a quantum region can be obtained via quantumreg_numM:

  • quantum_gridM(i,j,k) contains the quantum region number for point (i,j,k) on physical grid
  • quantumreg_numM(i,j,k) contains the point number (1..dim_qrV(n)) of the point (i,j,k) within the corresponding quantum region.
  • The inverse of this mapping is stored in inv_quantumreg_numM(1:num_qr_regions,1:max(dim_qrV),1:3):
    inv_quantumreg_numM(n,iqr,1:3) contains for quantum region n and point number iqr within quantum region n the coordinates (i,j,k) of the corresponding point on the physical grid.
  • One can also do this mapping between quantum region points and Stefan's grid (i.e. including multiple points):
    dim_qr_dbleV contains for each quantum region the number of points including multiple points (Note: For any point (i,j,k) on the physical grid all multiple points which are on the position of (i,j,k) are included. This also applies to boundary points.)
    quantumreg_num_dbleV(adr) provides for point number adr on Stefan's grid (adr=1..lengvecV) the point number within the corresponding quantum region.

map_qr_guentherV(1:num_qr_regions)  [MODULE gitter] contains for each quantum region the grid points, which are contained in that quantum region on material grid (i.e. the point numbers on material grid):

  • map_qr_guentherV(num_qr)%number_of_points -->  number of points
  • map_qr_guentherV(num_qr)%guenther_grid_points(1..number of points) -->
    position of the point on material grid

Often one wants to know the inverse mapping: Given a point on material grid, the position of that point in the set defined by map_qr_guentherV(num_qr)%guenther_grid_points(1..number of points) is obtained via:

number_guent_whole_to_qr(i_guent)    [ is zero for i_guent not in a quantum region ].

Thus, it is: number_guent_whole_to_qr(map_qr_guentherV(num_qr)%guenther_grid_points(k)) = k


MODULE gitter also contains the normalization vectors for the wavefunctions in each quantum cluster:

norm_sgV(1..num_qc,1..dim_qrV)  :   The norm is defined as:

< Psi | Psi > = sum( PsiV*PsiV*norm_sgV(num_qc,:) )

Note: norm_sgV is used to normalize wavefunctions for k.p and single-band Schrödinger equation.
In 1D, however, norm_sgV does not exist (Comment: Is this true? It exists for single-band! And it seems that it is necessary in order to normalize the wavefunction to '1'.) and the normalization vector for k.p is norm_kpV in MODULE normalization_factors_sg.


For treating Schrödinger equation it is necessary to know which band number is valid since in a quantum region different material numbers may be present and the band numbering and order is just proposed to be consistent within one material, we have to distinguish between different material kinds in a quantum region:

This is done by

map_qr_to_materialV(1..num_materials,1..num_qr_regions)

                                      1    2     ...         num_materials
                                     --------------------------------------

                                1   | 0    1     ...           2
                                     |
                                2   | 1    2     ...           0
                                     |
                                 .   |
                                 .   |
                                 .   |
                                     |
         num_qr_regions     | 0    0     ...           0
                                      ---------------------------------------

means that in quantum regions number 1

  • Index 1 refers to material 2.
  • Index 2 refers to material 'num_materials'.
  • Material number 1 is not contained in quantum regions number 1.

in quantum regions number 2

  • Index 1 refers to material 1.
  • Index 2 refers to material 2.
  • Material number 'num_materials' is not contained in quantum region number 2.

The following picture illustrates and summarizes the grid conventions:

 
     

 

 

3. Structure Functions (Grid mapping, ...)

There are several subroutines in MODULE structure_functions which help to handle grid mappings:

 

3.1  3D

MODULE structure_functions contains

1. subroutine get_octants_3D

2. subroutine get_octants_qr3D

3. subroutine convert_guenther_to_phys3D

4. subroutine get_addresses_from_phys3D

5. function   get_address3D

 

!-----------------------------------------------------------------------------
subroutine get_octants_3D(i,j,k,materialV)
!-----------------------------------------------------------------------------
!
! input: i,j,k
! output: materialV(1:8)
!
! provides for point (i,j,k) on physical grid the material numbers of each
! oktand (i=1..n_1,j=1..n_2,k=1,n_3)
! see in 2D for  an example
!-----------------------------------------------------------------------------

!-----------------------------------------------------------------------------
subroutine get_octants_qr3D(i,j,k,qu_regV)
!-----------------------------------------------------------------------------
!
! input: i,j,k
! output: qu_regV
!
! provides for point (i,j,k) on physical grid the quantum region of each
! oktand
! see in 2D for an example
!-----------------------------------------------------------------------------

!----------------------------------------------------------------------------
subroutine convert_guenther_to_phys3D(i_j_k,coordM)
!----------------------------------------------------------------------------
!
! input: i_j_k
! output: coordM(1:8,1:4)
!
! i_j_k number in guenthers whole vector
! coordM(i,1:3) coordinates on physical grid of adjoining grid points in octant  number i
! coordM(i,4) address of point in that octant from that point of view
! at boundaries the adjoining octant is valid
!
! see in 2D for an example
!----------------------------------------------------------------------------

!---------------------------------------------------------------------------
subroutine get_addresses_from_phys3D(i,j,k,octV)
!---------------------------------------------------------------------------
!
! input: i,j,k
! output: octV(1:8)
!
! provides for point (i,j,k) on physical grid in
! octV(1..8) the address in the whole vector of the eight octants
!
! see in 2D for an example
!------------------------------------------------------------------------

!----------------------------------------------------------------------------
function get_address3D(i,j,k,ch) result(adr)
!----------------------------------------------------------------------------
! returns for a point (i,j,k) on stefan's grid and 
! ch='n' for a single point
! (ch = '1',...'8' being the number of the octant otherwise)
! the address in the whole one-dim. vectors
!
! see in 2D for an example
!----------------------------------------------------------------------------

 

3.2  2D

MODULE structure_functions contains

1. subroutine get_octants_2D

2. subroutine get_octants_qr2D

3. subroutine convert_guenther_to_phys2D

4. subroutine get_addresses_from_phys2D

5. function   get_address2D

 

!-----------------------------------------------------------------------------
subroutine get_octants_2D(i,j,materialV)
!-----------------------------------------------------------------------------
!
! input: i,j
! output: materialV(1:4)
!
! provides for point (i,j) on physical grid the material numbers of each
! oktand (i=1..n_1,j=1..n_2)
!
! example:
!
! Imagine following situation: mat_i denotes the material number (mat2=material number 2,
!                                                                                             mat3=material  number 3)
! These material numbers are given on Guenther's grid. We consider now the situation (on the material grid):
!                                     .         .
!                                     .         .
!                                     .         .
!                            ...    mat7  mat2   ...
!                            ...    mat3  mat4   ...
!                                     .          .
!                                     .          .
!                                     .          .
!
!  on the physical Grid we have following situation:
!
!                                    (i,j+1)
!                                       |
!                         mat7       |       mat2
!                                       |
!                  (i-1,j)------------(i,j)--------------(i+1,j)
!                                       |
!                         mat3       |        mat4
!                                       |
!                                    (i,j-1)
!
! --> OUTPUT:
!        materialV(1)=mat3
!        materialV(2)=mat4
!        materialV(3)=mat7
!        materialV(4)=mat2
!-----------------------------------------------------------------------------

!-----------------------------------------------------------------------------
subroutine get_octants_qr2D(i,j,qu_regV)
!-----------------------------------------------------------------------------
!
! input: i,j
! output: qu_regV(1:4)
!
! provides for point (i,j) on physical grid the quantum region of each
! oktand
!
! example:
!
! Imagine following situation: qr_i denotes the quantum region number (=0, if not contained in any quantum region).
! These quantum region numbers are originally given on Guenther's grid. We consider now the situation (on the
! material grid):
!                                     .         .
!                                     .         .
!                                     .         .
!                            ...    qr1       0   ...
!                            ...     0         0   ...
!                                     .          .
!                                     .          .
!                                     .          .
!
!  on the physical Grid we have following situation:
!
!                                    (i,j+1)
!                                       |
!                         mat7       |       mat2
!                                       |
!                  (i-1,j)------------(i,j)--------------(i+1,j)
!                                       |
!                         mat3       |        mat4
!                                       |
!                                    (i,j-1)
!
! --> OUTPUT:
!        materialV(1)=0
!        materialV(2)=0
!        materialV(3)=qr1
!        materialV(4)=0
!
! NOTE:
!------------
!
! This subroutine is only used to construct the array quantum_gridM(i,j,1) out of the information
! of the input parser. Later on in the program, for each point on the physical Grid (i,j) the array
!  quantum_gridM(i,j,1) says if this point is contained in a quantum reagion.
!-----------------------------------------------------------------------------

!----------------------------------------------------------------------------
subroutine convert_guenther_to_phys2D(i_j_k,coordM)
!----------------------------------------------------------------------------
!
!
! input: i_j_k
! output: coordM(1:4,1:3)
!
! i_j_k number in guenthers whole vector
! coordM(i,1:2) coordinates on physical grid of adjoining grid points
! coordM(i,3) address of point in that octant from that point of view
! at boundaries the adjoining octant is valid
!
! example:
!
! material grid (2x2 grid -> points numbered from 1...4):
!
!      g3      g4
!      g1      g2
!
! --> physical Grid:
!
!   (1,3)     (2,3)      (3,3)
!          g3        g4
!   (1,2)     (2,2)      (3,2)
!          g1        g2
!   (1,1)     (2,1)      (3,1)
!
! Suppose that g1 and g3 have the same material A, g2 and g4 the same material B (A different from B)
! Then the points (2,1),(2,2),(2,3) on the physical grid are double points.
! So the numbering in the whole vector (1..lengvecV) is as follows:
!
!  9      10|11    12
!       g3       g4
!   5       6|7       8
!       g1       g2
!   1       2|3       4
!
! so for example:
!
! input: i_j_k=g3
!
! output: coordM(1,1:2) = (1,2)
!            coordM(2,1:2) = (2,2)
!            coordM(3,1:2) = (1,3)
!            coordM(4,1:2) = (2,3)
!
!            coordM(1,3) = 5
!            coordM(2,3) = 6
!            coordM(3,3) = 9
!            coordM(4,3) = 10
!----------------------------------------------------------------------------

!---------------------------------------------------------------------------
subroutine get_addresses_from_phys2D(i,j,octV)
!---------------------------------------------------------------------------
! input: i,j
! output: octV(1:4)
!
! provides for point (i,j) on physical grid in
! octV(1..4) the address in the whole vector of the four octants
!
! take the example above:
!
! material grid (2x2 grid -> points numbered from 1...4):
!
!      g3      g4
!      g1      g2
!
! --> physical Grid:
!
!   (1,3)     (2,3)      (3,3)
!          g3        g4
!   (1,2)     (2,2)      (3,2)
!          g1        g2
!   (1,1)     (2,1)      (3,1)
!
!  Suppose that g1 and g3 have the same material A, g2 and g4 the same material B (A different from B)
!  Then the points (2,1),(2,2),(2,3) on the physical Grid are double points.
!  So the numbering in the whole vector (1..lengvecV) is as follows:
!
!  9      10|11    12
!       g3       g4
!   5       6|7       8
!       g1       g2
!   1       2|3       4
!
! input: i=2, j=2
!
!  -->  the four octants have the addresses:     6 | 7
!                                                                 ----------
!                                                                  6 | 7
!
! so: octV(1)=  6
!       octV(2)= 7
!       octV(3)= 6
!       octV(4)= 7
!
!------------------------------------------------------------------------

!----------------------------------------------------------------------------
function get_address2D(i,j,ch) result(adr)
!----------------------------------------------------------------------------
! returns for a point (i,j) on stefan's grid and 
! ch='n' for a single point
! (ch = '1',...'4' being the number of the octant otherwise)
! the address in the whole one-dim. vectors
!
! in the above example:
!
! input : i=2, j=2 , ch='1' --> adr = octV(1) = 6
!           i=2, j=2 , ch='2' --> adr = octV(2) = 7
!           i=2, j=2 , ch='3' --> adr = octV(3) = 6
!           i=2, j=2 , ch='4' --> adr = octV(4) = 7
!----------------------------------------------------------------------------

 

3.3  1D

MODULE structure_functions contains

1. subroutine get_octants_1D

2. subroutine get_octants_qr1D

3. subroutine extract_octants1D


subroutine get_octants_1D(i,materialV)

Provides for point (i) on Stefan's grid the material numbers of each oktant (i=1..n_1)
(left and right octant).


subroutine get_octants_qr1D(i,qu_regV)

Provides for point (i) on Stefan's grid the quantum region numbers of each oktant.


subroutine extract_octants1D(octV,i)

Extracts from vector vecV(1:lengvecV) the two relevant octants for point with coord (i) on Stefan's grid: octV(1..2)


 

 

4. Rotations

There are principally two coordinate systems as described:

  1. Crystal system
  2. a) Simulation system
    b) Calculation system)

For a fixed vector k_vec the relation holds:

  k_vec{simulation-system} = RM . k_vec{crystal-system}
 
  ksi = R.kcr

This rotation matrix RM is provided by the function rotate_crystal_to_sim in MODULE rotations.

 

Transformation: Crystal fixed cartesian coordinate system -> Simulation coordinate system

There are two coordinate systems:

  • Crystal system
    describes a vector in terms of the basis vectors in the crystal system.

    In wurtzite these basis vectors are by default:
      miller-direction-of-cx           x   =  1  0 -1  0
      miller-direction-of-cy           y   = -1  2 -1  0
      miller-direction-of-cz           z   =  0  0  0  1
    where the directions are defined as [h k i l] with i=-(h+k). In wurtzite the four-digit indices are called Miller-Bravais indices.

    In zincblende they are defined by:
      miller-direction-of-cx           x   = 1 0 0
      miller-direction-of-cy           y   = 0 1 0
      miller-direction-of-cz           z   = 0 0 1
    Note that the crystal is a cartesian system.
  • Simulation system
    The simulation system is a cartesian system (x, y, z) in which the simulation variables are defined.

The relative position of the simulation system to the crystal system is unambigously determined. Thus the rotation matrix R can be defined as follows:

ksimulation=R.kcrystal

for a fixed vector k.

Note that in the rotation of the k.p Hamiltonian the rotation matrix was defined the same way as the rotation matrix above.

 

The crystal is oriented with respect to the simulation coordinate system by specifying two simulation coordinate axes in terms of Miller directions in the crystal. In this way, the orientation of the crystal is uniquely defined with respect to the simulation coordinate system. However, orientation dependent material parameters have to be defined in the database also with respect to a crystal fixed coordinate system. These axes of crystal fixed cartesian coordinate systems are defined in the database by their Miller directions in the crystal. In wurtzite the four-digit indices are called Miller-Bravais indices.
Note, that the choice is in such a way, that the orientation of the crystal fixed cartesian coordinate system is independent of the lattice constants.

For wurtzite materials, this crystal fixed cartesian coordinate system is chosen as

  miller-direction-of-cx              =  1  0 -1  0        !
  miller-direction-of-cy              = -1  2 -1  0        !
  miller-direction-of-cz              =  0  0  0  1        !

and for zincblende materials as

  miller-direction-of-cx              = 1 0 0              !
  miller-direction-of-cy              = 0 1 0              !
  miller-direction-of-cz              = 0 0 1              !

The transformation matrix B which transforms vectors, given in components of the crystal fixed cartesian coordinate system, to the simulation cartesian coordinate system is constructed in such a way, that

kxyz-simulation=  MATMUL(B,kxyz-crystal)

Up to the mass tensor of the band minima, all quantities in the database and the input must be given in the xyz-crystal system. The mass tensor is specified in its principal axes system.
The principal axes of the corresponding minima are specified in the xyz-crystal system for each material by its eigenvalues. To obtain the mass tensor in the simulation coordinate system, a transformation from the principal axis system to the xyz-crystal system is required. The corresponding transformation matrix can be accessed by

A=cb_trans_matrix_mass(mat_num,band_num,min,alloyc)

MCxyz =ATMp-axis A

A         ... transformation matrix
MCxyz   ... mass tensor in cartesian crystal coordinate system
Mp-axis  ... mass tensor in principal axis system

From the cartesian crystal coordinate system, the mass tensor transforms to the simulation cartesian coordinate system as

MSxyz = BMCxyzBT

 

 

4.1  1D simulation

In 1D, the simulation direction [=growth direction] can be the x-, y- or z-axis. In the program, however, one only has one direction (which is the z-direction) and parallel directions (x and y).
Consequently, one has to carry out an additional rotation, which rotates
the simulation direction to the z-direction (the ordering of x- and y-direction is unique in case one assumes an even permutation of the axes).

This additional rotation:

 k_vec{calculation-system} = RM k_vec{simulation-system}
  kca = R.ksi

is provided by the function rotate_sim_to_calculation in MODULE rotations.
(Note: In case the simulation direction is the z-axis in the simulation system, this rotation is the identity.)

function inv_rotate_sim_to_calculation in MODULE rotations calculates the inverse (=transpose) of this matrix.

Total rotation from crystal system to calculation system:

  k_vec{calculation-system} = R_gesM k_vec{crystal-system}
    kca = Rges.kcr

  R_gesM = RM_{simulation_to_calculation} . RM_{crystal_to_simulation}
    Rges = Rsi-ca.Rcr-si

This matrix is provided by the function rotate_crystal_to_calc in MODULE rotations.

NOTE: This is the matrix which is used for rotation of k.p-Hamiltonian because discretization is always carried out along z-direction in calculation system.

Transformation of matrices:

k_sim_1_T  E_sim  k_sim_2 = (RM k_cryst_1)T E RM k_cryst_2 =
 =  k_cryst_1_T RM_T  E_sim RM k_cryst_2  = k_cryst_1_T E_cryst k_cryst_2

 --->   E_cryst = RM_T  E_sim RM     and     E_sim = RM E_cryst RM_T

ksi1T.Esi.ksi2 = (R.kcr1)T.Esi.R.kcr2 =
 =  kcr1T.RT.Esi.R.kcr2  = kcr1T.Ecr.kcr2

 --->    Ecr = RT.Esi.R                                    and        Esi = R.Ecr.RT

 

4.2  2D simulation

In 2D, the simulation plane is determined by two of the  x-, y- or z-axes. In the program (= calculation system), however, one has two fixed directions (which form the (x,y) plane) and one perpendicular direction (z-axis).
Consequently, one has to carry out an additional rotation, which rotates
the simulation plane to the (x,y) plane (the ordering of x- and y-direction is unique in case one assumes an even permutation of the axes).

This additional rotation:

  k_vec{calculation-system} = RM k_vec{simulation-system}
 
kca = R.ksi

is provided by the FUNCTION rotate_sim_to_calculation in MODULE rotations.
(Note: In case the simulation directions are the (x,y)-plane in the simulation system, this rotation is the identity.)

FUNCTION inv_rotate_sim_to_calculation in MODULE rotations calculates the inverse (=transposed) of this matrix.

Total rotation from crystal system to calculation system:

  k_vec{calculation-system} = R_gesM k_vec{crystal-system}
 
kca = Rges.kc

  R_gesM = RM_{simulation_to_calculation} * RM_{crystal_to_simulation}
    Rges = Rsi-ca.Rcr-si

This matrix is provided by the FUNCTION rotate_crystal_to_calc in MODULE rotations.

NOTE: This is the matrix which is used for rotation of k.p-Hamiltonian because discretization is always carried out in (x,y)-plane in calculation system.

Question: When we have 2D simulation we can specify as simulation domain [1 0 1] or [1 1 0 ] or [0 1 1]. What is x and what is y in the simulation domain?

Answer:

[x y z] simulation system calculation sytem = x,y system
[1 0 1] (x,z)-plane x=x, y=z
[1 1 0] (x,y)-plane x=x, y=y
[0 1 1] (y,z)-plane x=y, y=z

 

4.3  3D simulation

In 3D, analogous functions are defined in MODULE rotations. Note that the calculation and simulation system are identical.

   
Last modified: 09-Jun-2011