IO#
- class nextnano_optimizers.io.IO(input_file_path: str, variable_names: list, target_output_paths: list, sweep: dict | None = None)#
Bases:
objectInterface between the nextnano input file, optimization variables, and simulation output datafiles.
- Parameters:
- input_file_pathstr
Path to a nextnano input file.
- variable_nameslist of str
Names of the input variables to be optimized. Each name must correspond to a variable defined in the input file.
- target_output_pathslist of tuple of str
Paths to the output files to be loaded after each simulation. Each tuple contains the path components relative to the simulation output directory.
Example one output:
[('bias_00000', 'potential.dat')]Example 2 outputs:
[('bias_00000', 'potential.dat'), ('Structure', 'AlloyConcentration.dat')]
- sweepdict, default=None
Input variables to sweep over, independently of the optimization. Each dictionary key must correspond to a variable defined in the input file and must not appear in
variable_names. Each dictionary value is a list of numerical values to sweep over.For each optimization candidate, one simulation is run for every combination of sweep values. For example,
{"source_bias": [-0.5, 0.0, 0.5]}results in three simulations per candidate.When
None, no sweep is performed and each candidate is simulated only once.
- Attributes:
- input_file_pathstr
Path to a nextnano input file.
- input_variable_nameslist of str
Names of the input variables to be optimized.
- target_outputlist of list or tuple
Paths to the output files to be loaded after each simulation.
- sweepdict or None
Input variables to sweep over.
- number_of_output_targetsint
Number of target output paths.
- number_of_input_variablesint
Number of input variable names.
- sweep_shapetuple of int
Number of values for each sweep variable. Empty tuple when there is no sweep. For example:
sweep = {"source_bias": [-0.5, 0.5], "well_width": [4, 5, 6]} sweep_shape = (2, 3)
- sweep_sizeint
Total number of sweep combinations, equal to the product of the elements of
sweep_shape(1 when there is no sweep).
- Raises:
- ValueError
If input variables are invalid.
Examples
Create an
IOinstance with three optimization variables and two target output files:>>> io = IO( ... input_file_path="device.nnp", ... variable_names=["well_width", "barrier_width", "doping"], ... target_output_paths=[ ... ("bias_00000", "potential.dat"), ... ("bias_00000", "quantum", "Gamma", "energies.dat"), ... ], ... )
To additionally run each simulations at different temperatures for each candidate, configure a sweep:
>>> io = IO( ... input_file_path="device.nnp", ... variable_names=["well_width", "barrier_width", "doping"], ... target_output_paths=[ ... ("bias_00000", "potential.dat"), ... ("bias_00000", "quantum", "Gamma", "energies.dat"), ... ], ... sweep={"temperature": [200, 300, 400]}, ... )
- load_output_datafiles()#
Load the simulation output datafiles specified in
target_output_paths.- Returns:
- numpy.ndarray or list
The return structure depends on the input to the latest
run_simulationcall:1D input, no sweep: array of shape
(k,).1D input, with sweep: array of shape
(k, *sweep_shape).2D input, no sweep: list of
Narrays of shape(k,).2D input, with sweep: list of
Narrays of shape(k, *sweep_shape).
Here,
kis the number of target output files andNis the number of optimization candidates. Each array containsnextnanopy.DataFileobjects. For 2D inputs, failed candidates are represented byNoneinstead of an array.
- Raises:
- RuntimeError
If
run_simulationhas not been called, or if the simulation for a single candidate failed.
Examples
Every example below assumes an
IOwith 2 output files intarget_output_pathsand 3 variables invariable_names. The shape of the returned datafiles depends on the input to the latestrun_simulationcall.Load the output datafiles after running a simulation for one candidate:
>>> io.run_simulation([5.0, 3.0, 1e17]) >>> datafiles = io.load_output_datafiles() >>> datafiles.shape (2,)
Load the output datafiles for multiple candidates:
>>> io.run_simulation([[5.0, 3.0, 1e17], [6.0, 3.5, 2e17]]) >>> datafiles = io.load_output_datafiles() >>> len(datafiles) 2 >>> datafiles[0].shape (2,)
Load the output datafiles when
iois configured withsweep={"temperature": [200, 300, 400]}:>>> io.run_simulation([5.0, 3.0, 1e17]) >>> datafiles = io.load_output_datafiles() >>> datafiles.shape (2, 3)
- run_simulation(input_variable_values, parallel_limit: int = 1, input_dir_path: str | None = None, output_dir_path: str | None = None, input_file_stem: str | None = None, clean_input_file: bool = False, start_index: int | None = None) None#
Run nextnano simulations for the given input variable values.
A 1D input runs simulations for a single optimization candidate, while a 2D input runs simulations for multiple candidates. If a sweep is configured,
sweep_sizesimulations are run for each candidate, one for each combination of sweep values.- Parameters:
- input_variable_values1D or 2D iterable
Values of the variables specified in
variable_names. A 1D input has a shape(m,), wheremis the number of optimization variables. A 2D input has shape(N, m), whereNis the number of candidates. Each row represents one candidate.- parallel_limitint, default=1
Maximum number of parallel simulations. 1 runs them serially.
- input_dir_pathstr, default=None
Directory the generated input files are saved in. If
None, they are saved next to the original input file.- output_dir_pathstr, default=None
Parent directory for the simulation output folders. Each simulation creates its own subfolder, named after the generated input file. If
None, the directory is determined by theoutputdirectorysetting in thenextnanopyconfiguration.- input_file_stemstr, default=None
Filename stem for generated input files. The stem is the filename without its extension (e.g.
"input_file", not"input_file.nnp"). IfNone, the original input filename stem is used.- clean_input_filebool, default=False
Whether to remove the generated input files after execution. Note: when running across multiple
run_simulationcalls in the sameinput_dir_path(e.g. successive evolution generations), keep thisFalsesonextnanopyauto-increments input filenames and produces unique output folders. SettingTruecauses filename — and therefore output folder — collisions.- start_indexint, default=None
Starting index for numbering generated input files, appended to the filename stem as a five-digit number. For example for
nnpfiles,input_file_stem="sim"andstart_index=5producesim_00005.nnp,sim_00006.nnpinput files andsim_00005,sim_00006output folders, etc. IfNone, file naming is handled bynextnanopy.
- Raises:
- ValueError
If the shape of
input_variable_valuesis incompatible withinput_variable_names, or ifinput_variable_valuesis empty.- FileExistsError
If
start_indexis given and a name it produces is already taken ininput_dir_path.
Examples
Run simulations for a single optimization candidate:
>>> io.run_simulation([5.0, 3.0, 1e17])
Run simulations for multiple optimization candidates:
>>> io.run_simulation([ ... [5.0, 3.0, 1e17], ... [6.0, 3.5, 2e17], ... [7.0, 4.0, 3e17], ... ])
Run simulations for multiple candidates in parallel, with at most two simulations running simultaneously:
>>> io.run_simulation([ ... [5.0, 3.0, 1e17], ... [6.0, 3.5, 2e17], ... [7.0, 4.0, 3e17], ... ], parallel_limit=2)