Temperature-dependent behaviors
Temperature-dependent behaviors implement the ITemperatureBehavior interface. It should contain any calculations that - as the name implies - are temperature-dependent.
This behavior can also be used to calculate properties that would otherwise be done inside much more frequently executed methods. Any expensive calculations that are not necessary inside other behaviors can be added to here.
Example - A diode
How would we create a temperature-dependent behavior for our diode model?
\(i_D = I_{SS}\left(e^\frac{v_A-v_B}{\eta V_T}\right)\)
We can see in the denominator that the multiplication of \(\eta\) and \(V_T = \frac{k\cdot T}{q}\) can be computed in the temperature-dependent behavior, because it is temperature-dependent and doesn't need to be re-evaluated every time the current/voltage changes.
using SpiceSharp;
using SpiceSharp.Behaviors;
using SpiceSharp.Entities;
using SpiceSharp.Simulations;
namespace SpiceSharpTest.DiodeBehaviors
{
/// <summary>
/// Temperature-dependent behavior for a diode.
/// </summary>
public class DiodeTemperature : Behavior, ITemperatureBehavior
{
private readonly ITemperatureSimulationState _temperatureState;
/// <summary>
/// Gets the diode parameters.
/// </summary>
protected DiodeParameters Parameters { get; }
/// <summary>
/// Gets the denominator in the exponent.
/// </summary>
protected double Vte { get; private set; }
/// <summary>
/// Creates a new temperature-dependent behavior
/// </summary>
/// <param name="context"></param>
public DiodeTemperature(IBindingContext context)
: base(context)
{
Parameters = context.GetParameterSet<DiodeParameters>();
_temperatureState = context.GetState<ITemperatureSimulationState>();
}
/// <summary>
/// Calculates temperature-dependent properties.
/// </summary>
public void Temperature()
{
Vte = Parameters.Eta * Constants.KOverQ * _temperatureState.Temperature;
}
}
}
The first thing to look at is the constructor. It accepts an IBindingContext. This interface provides access to:
- The entity or component parameters. In this case, we extract the diode parameters that we created ourselves. This method will throw an exception if the parameters don't exist.
- The simulation states. In this case we are interested in the simulation state that deals with temperature, meaning the ITemperatureSimulationState.
This temperature-dependent behaviors can serve as a base for other behaviors that can implement it, so I decided to have them protected. The other behaviors don't really need to deal with temperature, so I kept the simulation state private.
The only method in the class is fairly straight-forward. It is and should be called whenever the temperature changes, and it simply calculates the denominator of our diode equation.