# -*- coding: utf-8 -*-
# -------------------------------------------------------------
# Two-probe Configuration
# -------------------------------------------------------------
# -------------------------------------------------------------
# Left Electrode
# -------------------------------------------------------------

# Set up lattice
vector_a = [3.84001408591, 0.0, 0.0]*Angstrom
vector_b = [0.0, 3.84001408591, 0.0]*Angstrom
vector_c = [0.0, 0.0, 5.4306]*Angstrom
left_electrode_lattice = UnitCell(vector_a, vector_b, vector_c)

# Define elements
left_electrode_elements = [Silicon, Silicon, Silicon, Silicon]

# Define coordinates
left_electrode_coordinates = [[ 1.920007042956,  0.            ,  0.678825      ],
                              [ 1.920007042956,  1.920007042956,  2.036475      ],
                              [ 0.            ,  1.920007042956,  3.394125      ],
                              [ 0.            ,  0.            ,  4.751775      ]]*Angstrom

# Set up configuration
left_electrode = BulkConfiguration(
    bravais_lattice=left_electrode_lattice,
    elements=left_electrode_elements,
    cartesian_coordinates=left_electrode_coordinates
    )

# Add external potential
external_potential = AtomicCompensationCharge([
    ('doping_0', -0.00400390214212),
    ('doping_1', 0.00400390214212)
    ])

left_electrode.setExternalPotential(external_potential)

# -------------------------------------------------------------
# Right Electrode
# -------------------------------------------------------------

# Set up lattice
vector_a = [3.84001408591, 0.0, 0.0]*Angstrom
vector_b = [0.0, 3.84001408591, 0.0]*Angstrom
vector_c = [0.0, 0.0, 5.4306]*Angstrom
right_electrode_lattice = UnitCell(vector_a, vector_b, vector_c)

# Define elements
right_electrode_elements = [Silicon, Silicon, Silicon, Silicon]

# Define coordinates
right_electrode_coordinates = [[ 1.920007042956,  0.            ,  0.678825      ],
                               [ 1.920007042956,  1.920007042956,  2.036475      ],
                               [ 0.            ,  1.920007042956,  3.394125      ],
                               [ 0.            ,  0.            ,  4.751775      ]]*Angstrom

# Set up configuration
right_electrode = BulkConfiguration(
    bravais_lattice=right_electrode_lattice,
    elements=right_electrode_elements,
    cartesian_coordinates=right_electrode_coordinates
    )

# Add external potential
external_potential = AtomicCompensationCharge([
    ('doping_0', -0.00400390214212),
    ('doping_1', 0.00400390214212)
    ])

right_electrode.setExternalPotential(external_potential)

# -------------------------------------------------------------
# Central Region
# -------------------------------------------------------------

# Set up lattice
vector_a = [3.84001408591, 0.0, 0.0]*Angstrom
vector_b = [0.0, 3.84001408591, 0.0]*Angstrom
vector_c = [0.0, 0.0, 76.0284]*Angstrom
central_region_lattice = UnitCell(vector_a, vector_b, vector_c)

# Define elements
central_region_elements = [Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
                           Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon]

# Define coordinates
central_region_coordinates = [[  1.920007042956,   0.            ,   0.678825      ],
                              [  1.920007042956,   1.920007042956,   2.036475      ],
                              [  0.            ,   1.920007042956,   3.394125      ],
                              [  0.            ,   0.            ,   4.751775      ],
                              [  1.920007042956,   0.            ,   6.109425      ],
                              [  1.920007042956,   1.920007042956,   7.467075      ],
                              [  0.            ,   1.920007042956,   8.824725      ],
                              [  0.            ,   0.            ,  10.182375      ],
                              [  1.920007042956,   0.            ,  11.540025      ],
                              [  1.920007042956,   1.920007042956,  12.897675      ],
                              [  0.            ,   1.920007042956,  14.255325      ],
                              [  0.            ,   0.            ,  15.612975      ],
                              [  1.920007042956,   0.            ,  16.970625      ],
                              [  1.920007042956,   1.920007042956,  18.328275      ],
                              [  0.            ,   1.920007042956,  19.685925      ],
                              [  0.            ,   0.            ,  21.043575      ],
                              [  1.920007042956,   0.            ,  22.401225      ],
                              [  1.920007042956,   1.920007042956,  23.758875      ],
                              [  0.            ,   1.920007042956,  25.116525      ],
                              [  0.            ,   0.            ,  26.474175      ],
                              [  1.920007042956,   0.            ,  27.831825      ],
                              [  1.920007042956,   1.920007042956,  29.189475      ],
                              [  0.            ,   1.920007042956,  30.547125      ],
                              [  0.            ,   0.            ,  31.904775      ],
                              [  1.920007042956,   0.            ,  33.262425      ],
                              [  1.920007042956,   1.920007042956,  34.620075      ],
                              [  0.            ,   1.920007042956,  35.977725      ],
                              [  0.            ,   0.            ,  37.335375      ],
                              [  1.920007042956,   0.            ,  38.693025      ],
                              [  1.920007042956,   1.920007042956,  40.050675      ],
                              [  0.            ,   1.920007042956,  41.408325      ],
                              [  0.            ,   0.            ,  42.765975      ],
                              [  1.920007042956,   0.            ,  44.123625      ],
                              [  1.920007042956,   1.920007042956,  45.481275      ],
                              [  0.            ,   1.920007042956,  46.838925      ],
                              [  0.            ,   0.            ,  48.196575      ],
                              [  1.920007042956,   0.            ,  49.554225      ],
                              [  1.920007042956,   1.920007042956,  50.911875      ],
                              [  0.            ,   1.920007042956,  52.269525      ],
                              [  0.            ,   0.            ,  53.627175      ],
                              [  1.920007042956,   0.            ,  54.984825      ],
                              [  1.920007042956,   1.920007042956,  56.342475      ],
                              [  0.            ,   1.920007042956,  57.700125      ],
                              [  0.            ,   0.            ,  59.057775      ],
                              [  1.920007042956,   0.            ,  60.415425      ],
                              [  1.920007042956,   1.920007042956,  61.773075      ],
                              [  0.            ,   1.920007042956,  63.130725      ],
                              [  0.            ,   0.            ,  64.488375      ],
                              [  1.920007042956,   0.            ,  65.846025      ],
                              [  1.920007042956,   1.920007042956,  67.203675      ],
                              [  0.            ,   1.920007042956,  68.561325      ],
                              [  0.            ,   0.            ,  69.918975      ],
                              [  1.920007042956,   0.            ,  71.276625      ],
                              [  1.920007042956,   1.920007042956,  72.634275      ],
                              [  0.            ,   1.920007042956,  73.991925      ],
                              [  0.            ,   0.            ,  75.349575      ]]*Angstrom

# Set up configuration
central_region = BulkConfiguration(
    bravais_lattice=central_region_lattice,
    elements=central_region_elements,
    cartesian_coordinates=central_region_coordinates
    )

# Add external potential
external_potential = AtomicCompensationCharge([
    ('doping_0', -0.00400390214212),
    ('doping_1', 0.00400390214212)
    ])

central_region.setExternalPotential(external_potential)

device_configuration = DeviceConfiguration(
    central_region,
    [left_electrode, right_electrode],
    equivalent_electrode_lengths=[10.8612, 10.861199999999997]*Angstrom,
    )

# Add tags
device_configuration.addTags('doping_0', [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
                                          13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
                                          26, 27])
device_configuration.addTags('doping_1', [28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
                                          41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
                                          54, 55])

# -------------------------------------------------------------
# Calculator
# -------------------------------------------------------------
#----------------------------------------
# Basis Set
#----------------------------------------
basis_set = [
    BasisGGAPseudoDojo.Silicon_Low,
    ]

#----------------------------------------
# Exchange-Correlation
#----------------------------------------
exchange_correlation = GGAHalf.PBE

#----------------------------------------
# Numerical Accuracy Settings
#----------------------------------------
left_electrode_k_point_sampling = MonkhorstPackGrid(
    na=5,
    nb=5,
    nc=87,
    )
left_electrode_numerical_accuracy_parameters = NumericalAccuracyParameters(
    k_point_sampling=left_electrode_k_point_sampling,
    density_mesh_cutoff=30.0*Hartree,
    )

right_electrode_k_point_sampling = MonkhorstPackGrid(
    na=5,
    nb=5,
    nc=87,
    )
right_electrode_numerical_accuracy_parameters = NumericalAccuracyParameters(
    k_point_sampling=right_electrode_k_point_sampling,
    density_mesh_cutoff=30.0*Hartree,
    )

device_k_point_sampling = MonkhorstPackGrid(
    na=5,
    nb=5,
    nc=87,
    )
device_numerical_accuracy_parameters = NumericalAccuracyParameters(
    k_point_sampling=device_k_point_sampling,
    density_mesh_cutoff=30.0*Hartree,
    )

#----------------------------------------
# Poisson Solver Settings
#----------------------------------------
left_electrode_poisson_solver = FastFourier2DSolver(
    boundary_conditions=[[PeriodicBoundaryCondition(),PeriodicBoundaryCondition()],
                         [PeriodicBoundaryCondition(),PeriodicBoundaryCondition()],
                         [PeriodicBoundaryCondition(),PeriodicBoundaryCondition()]]
    )

right_electrode_poisson_solver = FastFourier2DSolver(
    boundary_conditions=[[PeriodicBoundaryCondition(),PeriodicBoundaryCondition()],
                         [PeriodicBoundaryCondition(),PeriodicBoundaryCondition()],
                         [PeriodicBoundaryCondition(),PeriodicBoundaryCondition()]]
    )

#----------------------------------------
# Contour Integral Settings
#----------------------------------------
equilibrium_contour = SemiCircleContour(
    integral_lower_bound=1.5*Hartree,
    )
contour_parameters = ContourParameters(
    equilibrium_contour=equilibrium_contour,
    )

#----------------------------------------
# Electrode Calculators
#----------------------------------------
left_electrode_calculator = LCAOCalculator(
    basis_set=basis_set,
    exchange_correlation=exchange_correlation,
    numerical_accuracy_parameters=left_electrode_numerical_accuracy_parameters,
    poisson_solver=left_electrode_poisson_solver,
    )

right_electrode_calculator = LCAOCalculator(
    basis_set=basis_set,
    exchange_correlation=exchange_correlation,
    numerical_accuracy_parameters=right_electrode_numerical_accuracy_parameters,
    poisson_solver=right_electrode_poisson_solver,
    )

#----------------------------------------
# Device Calculator
#----------------------------------------
calculator = DeviceLCAOCalculator(
    basis_set=basis_set,
    exchange_correlation=exchange_correlation,
    numerical_accuracy_parameters=device_numerical_accuracy_parameters,
    contour_parameters=contour_parameters,
    electrode_calculators=
        [left_electrode_calculator, right_electrode_calculator],
    )

device_configuration.setCalculator(calculator)
nlprint(device_configuration)
device_configuration.update()
nlsave('silicon_pn_junction.hdf5', device_configuration)
