Input file basics#

Last update: 2026-08-07


All nextnano++ simulations are defined within input files with an extension .nnp which are organizing instructions for the simulation tool. These input files do not operate like scripts as they are not executed line-by-line, even though sometimes the order matters. Instead, they are first fully parsed by nextnano++ which then later runs models and procedures according to the specification. Hence the best way of thinking about the input files is as a simulation specifications or a text interface to the simulation tool nextnano++.

Keywords#

The control of the simulation is performed by defining speciffic keywords. There are two kinds of them: attributes and groups.

Function of groups is two-fold. First they trigger certain models and algorithms, second they organize other groups and attributes related to these models and algorithms. The groups are the keywords of which names are followed by curly brackets. For example, global{} is a group organizing general information about the simulation.

The attributes are such keywords which have a name and can have a value assigned. For example, temperature is an attribute which can hold a real number no smaller than 1e-9 expressed in K. Hence one can write temperature = 4.2 to request the simulation to be held for a system at 4.2 K.

Every keyword can be defined only within a certain scope. All groups like global{}, listed here, can be defined only outside of other groups. These are top-level groups. Each of them defines their own scope, which can contain either other groups (nested groups) or attributes. Every attribute must be located inside a group.

Below, teh example shows a top-level group global{} with an attribute temperature and a nested group simulate1D{} defined within its scope. This particular example instructs the solver that the simulation will be held for the temperature 4.2 K and it will be a 1D simulation.

global{
    temperature = 4.2
    simulate1D{}
    ...
}
...

Every keyword can be either required or optional within their scopes. For example, global{} group is required and this is top level group, hence it is required in every simulation. On the other hand a group region{} does not have to be present in every simulation since it every simulation even though is required, since it is nested inside quantum{} group which is optional. It must be present if quantum{} is defined

global{ ... }           # required in all simulations
quantum{                # optional
    region{ ... }       # required within the scope of quantum{}
}
...

If the group is marked as optional it does not mean that it never is required. Triggering one optional model may require others to be present. For example, to calculate optical spectra using Fermi’s golden rule, one needs to calculate quantum states, hence presence of optional quantum_spectra{} inside an optional optics{} makes quantum{} required for the simulation to run.

quantum{ ... }              # optional but required by quantum_spectra{}
optics{                     # optional
    quantum_spectra{ ... }  # optional
    ...
}
...

Most of these dependencies are documented on the sites describing specific keywords. If not, then upon running nextnano++ the simulation output (log file generated by nextnanomat) will end with instruction explaining what is missing or which conditions are not met.

Variables#

Syntax of nextnano++ supports also variables which are invaluable when defining complex simulations. They are also essential to enable treating the input files as templates in nextnanomat, running sweeps via nextnanopy, or optimizing simulations with nextnano optimizers. Each variable begins with a $ sign and contains a name that can contain letters, numbers, and underscores. The name of a variable cannot begin with a number.

$temperature = 4.2 # (K) temperature of the system
global{
    temperature = $temperature
    simulate1D{}
    ...
}
...

Variables can hold all typed of data that can be used within attributes. These are numbers, arrays of numbers, and strings.

$number = 5*1e18
$array  = [1, 1.5, 2]
$string = "GaAs"

Regular arithmetic and logical operations can be performed on variables, as well as they can be used as arguments of mathematical functions.

$L_x  = 10
$x_min = $L_x / 2
$x_max = $x_min + $L_x
$quantum = 1
$poisson = 1

$quantum_poisson = $quantum && $poisson

Variables can be defined and redefined anywhere in the input file and used multiple times. They do not belong to any scope. The example below, even though not practical, presents this property.

contacts{
    ohmic{
        $bias = 1
        name = "source"
        bias = $bias    # electrochemical potential set to 1 V
    }
    $bias = 2*$bias
    ohmic{
        name = "drain"
        bias = $bias    # electrochemical potential set to 2 V
    }
}

Organizing the input file#

Typically we begin input files with all variables defined. First we organize variables that have explicitly assigned some values. These allow for convenient control of the defined simulation. Then we put derived variables.

# Variables allowing comfortable simulation control

$quantum = 1
$poisson = 1
$L_x  = 10

# Derived variables

$x_min = $L_x / 2
$x_max = $x_min + $L_x
$quantum_poisson = $quantum && $poisson

Then the instructions for nextnano++ begin with a set of top-level groups.

Every simulation requires groups listed below to provide minimum definition of a system to be simulated.

Group

Purpose

run{ }

triggers models and controls self-consistent loops

global{ }

defines global properties of the entire simulation domain

contacts{ }

defines boundary conditions which can be further used in structure definition

structure{ }

defines device/structure layout by assigning materials, doping, and boundary conditions to specified regions, the order of some groups matter here

grid{ }

defines numerical grid

classical{ }

specifies which bands are going to enter the simulation and controls bulk models

The remaining groups are optional. For simulations where doping must be defined, one would need to add the group impurities{ }. The import{ } group would be used for designs requiring importing strain or composition from external files or analytical functions. It also allow importing global optical spectra. These all 6 required and 3 optional groups exhaust definition of the device or structure.

The next are 5 major groups controlling all physical models.

Group

Purpose

strain{ }

selects and configures strain model

poisson{ }

initializes the Poisson equation

currents{ }

controls mobility and recombination models

quantum{ }

defines regions for the Schrödinger equation, selects and configures band models, and controls multiple related features

optics{ }

selects and configures models for calculations of optical spectra

On top of these, there is also a group splitquantum{ } enabling and configuring approximate semi-quantum calculation of carrier densities.

Further there are two helper groups

Group

Purpose

output{ }

controls output formats, configures data slices, enables certain additional outputs

postprocessor{ }

enables running external scripts directly after simulation if finished

Finally there is a special group database{ }, which allows defining custom materials and overwriting these from the database used during simulation.

Note

Order of the top-level groups in the input file is irrelevant.

Output of the input file#

There are two output files that help investigating complex input files. The first one is variables_input.dat. It contains a list of all variables defined in the input file with the final values evaluated for them. The entire input file without comments and with all variables replaced with their respective values in all places where they were used can be found in simulation_input.txt. For example, a piece of an input file

$temperature = 4.2 # (K) temperature of the system
$material = "GaAs"
$hkl_growth = [1, 0, 0]

global{
    temperature = $temperature
    simulate1D{}                # choose between 1D, 2D or 3D simulation
    substrate{ name = "GaAs" }  # substrate material (required)
    crystal_zb{                 # crystal orientation
        x_hkl = $hkl_growth     # x-axis is perp. to lattice plane (100)
        y_hkl = [0, 1, 0]       # y-axis is perp. to lattice plane (010)
    }
}

contacts{
    ohmic{
        $bias = 1
        name = "source"
        bias = $bias    # electrochemical potential set to 1 V
    }
    $bias = 2*$bias
    ohmic{
        name = "drain"
        bias = $bias    # electrochemical potential set to 2 V
    }
}

would produce variables_input.dat

$temperature = 4.2
$material = "GaAs"
$hkl_growth = [ 1, 0, 0 ]
$bias = 2

and simulation_input.txt

global{
    temperature = 4.2
    simulate1D{
    }
    substrate{
        name = "GaAs"
    }
    crystal_zb{
        x_hkl = [ 1, 0, 0 ]
        y_hkl = [ 0, 1, 0 ]
    }
}
contacts{
    ohmic{
        name = "source"
        bias = 1
    }
    ohmic{
        name = "drain"
        bias = 2
    }
}