Optimizing well width for specific target transition energy in an infinite quantum well#
Header#
- Relevant files
1D_IntersubbandAbsorption_InfiniteWell_GaAs_Chuang_sg_nnp.in
InfiniteWell_example.py (not public yet, provided on request)
- Relevant output files:
bias_00000/Quantum/energy_spectrum_quantum_region_Gamma_00000.dat
- Scope
design optimization
quantum well
transition energies
- Important variables
$QuantumWellWidth= thickness of the GaAs quantum well
Introduction#
This tutorial demonstrates the use of nextnano optimizers for optimization of a simple quantum well structure to achieve desired transition energy. The tutorial is based on the Intersubband absorption of an infinite quantum well tutorial.
Objective#
The goal of this optimization is to determine the quantum well thickness that aligns the transition between the first and second electron states with a specified target energy.
Variables under optimization:
Name |
Units |
Initial value |
Bounds |
|---|---|---|---|
QuantumWellWidth |
nm |
10.0 |
– |
Target output:
Name |
Units |
Initial value |
Target |
|---|---|---|---|
Transition energy |
eV |
0.1668 |
0.1 |
Scipy.optimize.minimize#
In this example the scipy.optimize.minimize algorithm is used. The metric measures the distance to the target,
where \(x\) represents the vector of input variables and \(g\) is the user-defined transition energy. The minimizer drives \(f\) to zero, which happens exactly where \(g\) reaches the target.
Optimization script#
Initially, create a nextnano_optimizers.IO instance specifying the input file, optimization variables, and output files relevant for the metric.
from nextnano_optimizers.IO import IO
nn_io = NextnanoIO(input_file_path,
variable_names=['QuantumWellWidth'],
target_output_paths=[('bias_00000', 'Quantum', 'energy_spectrum_quantum_region_Gamma_00000.dat')])
Next, define the metric function. It extracts the transition energy from the energy_spectrum datafile and returns how far that is from the target.
TARGET_TRANSITION_ENERGY = 0.1 # eV
def distance_to_target_transition(df_list):
df_energy_spectrum = df_list[0] # df_list will be a list containing one datafile
energy_spectrum = df_energy_spectrum.variables['Energy'].value
transition_energy = energy_spectrum[1] - energy_spectrum[0] # transition energy between the ground state and second state
return np.array([abs(transition_energy - TARGET_TRANSITION_ENERGY)])
The target belongs in the metric rather than in the optimizer. What is being measured is “how far from the target am I”, so the objective is smallest exactly where the design matches, and the optimizer’s job is simply to drive it to zero – which any minimizer can do.
Note that abs has a kink at the minimum, which is the shape derivative-based methods handle worst. Use a derivative-free method such as Nelder-Mead or Powell. If you would rather use a gradient-based method, square the difference instead – (transition_energy - TARGET_TRANSITION_ENERGY)**2 is smooth and has its minimum in the same place.
A nextnano_optimizers.Metric is created with the custom metric function. Extraction function takes single output file and converts it to single value, so both input length and output length equal 1.
from nextnano_optimizers.MetricExtractor import Metric
metric = Metric(input_length=1, output_length=1, extraction_function=distance_to_target_transition)
Create the LocalOptimizer.
from nextnano_optimizers.optimizer import LocalOptimizer
optimizer = LocalOptimizer(nextnanoio=nn_io, metric=metric)
Run the optimization, passing the initial quantum well thickness and the scipy.optimize.minimize arguments. The details are recorded in the Simulation*.log file, which tracks each input file execution, alongside a Simulation*.json log and a Simulation*.dat table holding one entry per function evaluation.
result = optimizer.run(x0=np.array([10]), method='Nelder-Mead')
print(f"The optimal quantum well thickness is {result.x} nm")
Output:
The optimal quantum well thickness is [12.80762256] nm
The figure below shows the transition energy as a function of quantum well width, indicating the initial and optimized designs.
Figure 9 Transition energy between 1st and 2nd state in a quantum well as a function of quantum well width#
Conclusion#
In summary, this tutorial has demonstrated an approach to optimize a quantum well structure to match a specific transition energy using nextnano optimizers. The process involved setting up the NextnanoIO instance, defining a custom metric function, utilizing the NextnanoMetricExtractor, and finally employing the NextnanoOptimizer for the actual optimization task.