pynitride.physics.solvers module¶
- class pynitride.physics.solvers.Equilibrium(mesh)¶
 Bases:
objectSimplest Fermi solver, E_F=0 everywhere.
- Parameters:
 mesh – the
Meshon which to perform the solve
- solve()¶
 Sets E_F=0 everywhere.
- class pynitride.physics.solvers.Linear_Fermi(mesh, contacts={'gate': 0, 'subs': -1})¶
 Bases:
objectAllows for a specified piecewise linear Fermi potential.
An arbitrary number of “contacts” can be designated, and at each of these locations, a call to
solve()may specify a voltage.- Parameters:
 mesh – the
Meshon which to perform the solvecontacts – a dictionary mapping names of contacts to locations in the mesh. Keys are arbitrary names, values are either (1) integers, in which case they will be interpreted as designating a layer interface (0 is the top surface, -1 is the bottom point), or (2) floats, in which case they will be interpreted as designating a nearest point to a z-value
- solve(**voltages)¶
 Sets the Fermi level to a linear interpolation of the specific values
- Parameters:
 **voltages – keyword arguments of the form name=voltage where name is one of the keys to the contacts dictionary supplied at initialization.
- class pynitride.physics.solvers.PoissonSolver(mesh)¶
 Bases:
objectSolves the Poisson equation on a mesh.
The boundary conditions assumed are Dirichelet at the surface (ie fixed surface barrier) and Neumann at the bottom (ie thick substrate). Accounts for charge from (1) carriers which are filled into mesh[‘n’] and mesh[‘p’] by some Carrier Model (2) polarization which is filled into mesh[‘P’] (generally by the MaterialSystem), differentiating that to fill mesh[‘DP’], and (3) dopants which for which the values are drawn from the mesh (see
ionized_dopants()).Two solve functions are available:
solve()andnewton_step(). The former is a direct solution, which can be obtained directly from charge integration. The latter is a Newton-method solver appropriate for self-consistent iteration with a carrier solver. For use with this method, the carrier models must implement not just n and p but also nderiv and pderiv to supply the relevant derivative information.A static convenience function
update_bands_to_potential()is also available to set bands for simulations where the Poisson equation is not needed.- Parameters:
 mesh – the
Meshon which to perform the solve
- static get_sbh(m)¶
 Get the surface barrier for a given mesh.
If the mesh boundary is specified numerically, that’s the surface barrier, otherwise asks the topmost material system for it’s surface barrier given the mesh.
- Parameters:
 m – the global
Mesh- Returns:
 the surface barrier (float)
- ionized_dopants()¶
 Computes the ionized dopant densities and their derivatives
Fills the values Ndp, Ndpderiv, Nam, Namderiv onto the mesh for the total ionized donor and acceptor densities and derivatives.
- newton_step(activation=1)¶
 Solves the phi for one step of Newton iteration.
The equation is \(-\left[\partial_z\epsilon\partial_z+\rho_0'\right]\delta\phi=\rho + \partial_z\epsilon\partial_z\phi_0\).
- Parameters:
 activation – a factor (generally <=1) by which to multiply the determined change \(\delta\phi\) before adding it.
- restore_state()¶
 Restores the most recently saved phi.
Useful in iterative self-consistent solves for returning back to “the last point where things worked”. See
store_state().
- shorten_last_step(factor)¶
 Shortens the phi step taken by the most recent solve by the given factor.
- Parameters:
 factor (float) – the amount (0-1) by which the previous step should be rescaled
- solve()¶
 Solves the Poisson equation directly (not good for self-consistent looping)
The equation is \(-\partial_z\epsilon\partial_z\phi=\rho\). Do not use this function in a self-consistent poisson-carrier loop, because that’s not super stable. Instead use
newton_step().
- store_state()¶
 Stores the current phi in case we want to return to this current solution.
Useful in iterative self-consistent solves for returning back to “the last point where things worked”. See
restore_state().
- static update_bands_to_potential(m, phi=None, sbh=None)¶
 Updates Ec, Ev, and phi to match the phi (potential) given.
- Parameters:
 m – the
Meshphi – the new phi to use (MidFunction or scalar), None to just use current
sbh – the surface potential, if not specified, will be calculated from the mesh
- update_epsfactor(epsfactor)¶
 Scales the epsilon used by this solver without actually changing epsilon on the mesh.
The higher the epsfactor, the less coupling between phi and charge, iterative solutions are easier. The resulting solution is, of course, not correct for epsfactor!=1, but ramping epsfactor from a large value where the problem is easy down to 1 is a useful way to smoothly approach the solution.
- Parameters:
 epsfactor – the factor (generally >=1) by which epsilon should be scaled
- class pynitride.physics.solvers.SelfConsistentLoop(fieldsolvers=[], carriermodels=[])¶
 Bases:
objectFor Newton-iteration of field and carrier solvers.
Dielectric ramping is provided for initial solutions and carrier models can be swapped in and out to allow for sequential solves by different methods.
- Parameters:
 fieldsolvers – a list of
PoissonSolvercarriermodels – a list of
CarrierModel
- add_carrier_model(cs)¶
 Add a carrier solver for consideration.
- Parameters:
 cs – a
CarrierModel
- loop(tol=1e-05, max_iter=100, min_activation=0.05, init_activation=1, dec_activation=2, inc_activation=1.1, max_activation=1)¶
 Loops the Newton field solution and carrier models until they agree
If the error increases during a step, the step will be retried with a smaller activation (see
newton_solve()). If the activation becomes too small or the maximum number of iterations is passed, will raise an exception.Note, the first step in the solve is always the carriers, so they may be in any state before this function is called, whereas the fields must already be defined, eg by
update_bands_to_potential().- Parameters:
 tol – the absolute tolerance for the error as returned by
newton_step()max_iter – Maximum number of iterations allowed (not including any lower-activation re-attempts made)
min_activation – the smallest activation allowed.
init_activation – activation to start looping at
dec_activation – factor by which to reduce the activation if a step fails
inc_activation – factor by which to increase the activation if a step succeeds
- newton_fields(activation=1)¶
 Perform one Newton step of the fields (just the fields, not the carriers).
Calls the
newton_step()for each field solver.- Parameters:
 activation – the proportion by which to change the fields (see ~pynitride.solvers.PoissonSolver.newton_step)
- Returns:
 the summed error from each field solver’s newton_step
- ramp_epsfactor(start=10000.0, stop=1, dlefstart=0.1, dlefmax=0.5, dlefmin=0.005, **loop_opts)¶
 Ramp the dielectric constant for an easy initial condition.
Performs self-consistent loops at successive values of the epsfactor (see
update_epsfactor()) from start until the stop value is reached. If the loops do not converge, smaller steps of the epsilon factor are attempted, this robustness is controlled by the dlef arguments, which constrain dlef (the logarithmic change in the epsilon factor from step to step, ie log10(epsfactor) changes by dlef). If the step cannot be reduced further but the loop does not converge, an exception will be raised.- Parameters:
 start – initial value of epsfactor
stop – final value of epsfactor
dlefstart – initial logarithmic delta for epsfactor stepping
dlefmax – maximum allowed logarithmic delta for epsfactor stepping
dlefmin – minimum allowed logarithmic delta for epsfactor stepping
loop_opts – passed to each pynitride.solvers.SelfConsistentLoop.loop
- ramp_temperature(temp_solver, start=300, stop=300, dlTstart=0.025, dlTmax=0.1, dlTmin=0.005, **loop_opts)¶
 Ramp the temperature for an easy initial condition.
Performs self-consistent loops at successive values of the temperature from start until the stop value is reached. If the loops do not converge, smaller steps of the temperature are attempted, this robustness is controlled by the dlT arguments, which constrain dlT (the logarithmic change in the temperature from step to step, ie log10(temperature) changes by dlT). If the step cannot be reduced further but the loop does not converge, an exception will be raised.
- Parameters:
 start – initial value of temperature
stop – final value of temperature
dlTstart – initial logarithmic delta for temperature stepping
dlTmax – maximum allowed logarithmic delta for temperature stepping
dlTmin – minimum allowed logarithmic delta for temperature stepping
loop_opts – passed to each pynitride.solvers.SelfConsistentLoop.loop
- remove_carrier_model(cs)¶
 Remove a carrier solver from consideration.
- Parameters:
 cs – a
CarrierModelwhich should be in the list currently considered
- solve_carriers()¶
 Perform a direct solve of the carriers (just the carriers, not the fields).
Calls the
solve()for each.
- solve_fields()¶
 Perform a direct solve of the fields (just the fields, not the carriers).
Calls the
solve()for each field solver.
- swap_carrier_model(remove, add)¶
 Swaps out one
CarrierModelfor another- Parameters:
 remove – the model to remove
add – the model to add