.. _nnevo_scipy_infinite_well: Optimizing well width for specific target transition energy in an infinite quantum well ======================================================================================== .. attention:: |The_nextnanoevo_package| is under development. .. contents:: :local: :backlinks: none Header --------- Relevant files - :guilabel:`1D_IntersubbandAbsorption_InfiniteWell_GaAs_Chuang_sg_nnp.in` - :guilabel:`InfiniteWell_example.py` (not public yet, provided on request) Relevant output files: - :guilabel:`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 nextnanoevo for optimization of a simple quantum well structure to achieve desired transition energy. The tutorial is based on the :ref:`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: .. table:: ================ ======== ================= ======== Name Units Initial value Bounds ================ ======== ================= ======== QuantumWellWidth nm 10.0 -- ================ ======== ================= ======== Target output: .. table:: ================= ======== ================= ======== Name Units Initial value Target ================= ======== ================= ======== Transition energy eV 0.1668 0.1 ================= ======== ================= ======== Scipy.optimize.root ^^^^^^^^^^^^^^^^^^^ In this example scipy.optimize.root root-solver is used. The algorithm searches for the root of the equation .. math:: f(x) - target = 0 where :math:`x` represents the vector of input variables and :math:`f` is the user-defined metric. Optimization script ------------------- Initially, create a nextnanoevo.IO instance specifying the input file, optimization variables, and output files relevant for the metric. .. code:: Python from nextnanoevo.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 to extract the transition energy from the energy_spectrum datafile. .. code:: Python def first_transition_extraction_function(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([transition_energy]) A nextnanoevo.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. .. code:: Python from nextnanoevo.MetricExtractor import Metric metric = Metric(input_length=1, output_length=1, extraction_function=first_transition_extraction_function) Create the Optimizer, and set the initial value for quantum well thickness and target transition energy. .. code:: Python from nextnanoevo.OptimizerClass import Optimizer optimizer = Optimizer(nextnanoio=nn_io, metric=metric, optimization_method='root') # arguments of the optimization_method. For scipy optimize.root x0 is mandatory optimizer.set_optimization_parameters(x0=np.array([10])) # set target optimizer.set_target(np.array([0.1])) Run the optimization. The details are recorded in the Simulation*.log file, which tracks each input file execution. .. code:: Python result = optimizer.run_optimization() print(f"The optimal quantum well thickness is {result.x} nm") Output: .. code:: shell The optimal quantum well thickness is [12.80762256] nm Conclusion ---------- In summary, this tutorial has demonstrated an approach to optimize a quantum well structure to match a specific transition energy using nextnanoevo. 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.