1 #ifndef _NLCURRENTSOURCE_HPP_INC_
2 #define _NLCURRENTSOURCE_HPP_INC_
25 const size_t currentSolutionIndex, T timestep = 0)
const {
26 constexpr T alpha = 1.3;
27 constexpr T beta0 = 0.42;
28 constexpr T gamma = 0.0005;
29 constexpr T delta = 0.3;
30 constexpr T xi = 0.06;
31 constexpr T lambda = 1.5;
33 constexpr T zeta = 0.18;
34 constexpr T Vto = -2.4;
38 size_t r1p_pos =
r1_pos - 1;
39 size_t r1p_neg =
r1_neg - 1;
40 size_t r2p_pos =
r2_pos - 1;
41 size_t r2p_neg =
r2_neg - 1;
48 u = solutionMatrix(n1p, currentSolutionIndex);
52 u -= solutionMatrix(n2p, currentSolutionIndex);
56 r1 = solutionMatrix(r1p_pos, currentSolutionIndex);
60 r1 -= solutionMatrix(r1p_neg, currentSolutionIndex);
64 r2 = solutionMatrix(r2p_pos, currentSolutionIndex);
68 r2 -= solutionMatrix(r2p_neg, currentSolutionIndex);
73 using ADT = AD::DiffVar<T, 2>;
78 auto Vgst = V_gs - (1 + beta * beta) * Vto + gamma * V_ds;
79 auto Veff = 0.5 * (Vgst + AD::sqrt(AD::pow(Vgst, 2) + delta * delta));
80 auto power = lambda / (1 + mu * AD::pow(V_ds, 2) + xi * Veff);
81 auto area = alpha * V_ds * (1 + zeta * Veff);
82 auto f1 = AD::tanh(area);
83 auto Ids_lim = beta * AD::pow(Veff, power);
84 auto Idrain = Ids_lim *
f1;
85 auto I_ds = Idrain[0] - Idrain[1] * r1 - Idrain[2] * r2;
88 stamp.
s(n1p, 0) += -I_ds;
90 stamp.
G(n1p, r1p_pos) += Idrain[1];
93 stamp.
G(n1p, r1p_neg) += -Idrain[1];
96 stamp.
G(n1p, r2p_pos) += Idrain[2];
99 stamp.
G(n1p, r2p_neg) += -Idrain[2];
104 stamp.
s(n2p, 0) += +I_ds;
106 stamp.
G(n2p, r1p_pos) += -Idrain[1];
109 stamp.
G(n2p, r1p_neg) += Idrain[1];
112 stamp.
G(n2p, r2p_pos) += -Idrain[2];
115 stamp.
G(n2p, r2p_neg) += Idrain[2];
121 size_t numCurrents)
const {
128 size_t & numNodes,
size_t & numCurrents,
size_t & numDCCurrents) {
129 std::regex currentSourceRegex =
generateRegex(
"I",
"n n n n n n");
133 std::regex_match(line, matches, currentSourceRegex);
134 currentSource.
n1 = std::stoi(matches.str(2));
135 currentSource.
n2 = std::stoi(matches.str(3));
136 currentSource.
r1_pos = std::stoi(matches.str(4));
137 currentSource.
r1_neg = std::stoi(matches.str(5));
138 currentSource.
r2_pos = std::stoi(matches.str(6));
139 currentSource.
r2_neg = std::stoi(matches.str(7));
141 numNodes = std::max(numNodes, std::stoull(matches.str(2)));
142 numNodes = std::max(numNodes, std::stoull(matches.str(3)));
143 numNodes = std::max(numNodes, std::stoull(matches.str(4)));
144 numNodes = std::max(numNodes, std::stoull(matches.str(5)));
145 numNodes = std::max(numNodes, std::stoull(matches.str(6)));
146 numNodes = std::max(numNodes, std::stoull(matches.str(7)));
148 elements.nonLinearElements.emplace_back(
std::regex generateRegex(std::string indentifier, std::string simplifiedMatching, bool startAnchor=true, bool endAnchor=true)
a helper function to aid in the construction of regexes for parsing netlist files
common weighting for all matrix elements
a namespace to hold the messiness of my auto-differentiator
a glorified container for the different types of components.
A template base class to define the fundamental things a component should define.
A matrix class with support for LU-decomposition, and left division.
An non-linear current source for the COBRA transistor model.
static void addToElements(const std::string &line, CircuitElements< T > &elements, size_t &numNodes, size_t &numCurrents, size_t &numDCCurrents)
void addNonLinearStampTo(Stamp< T > &stamp, const Matrix< T > &solutionMatrix, const size_t currentSolutionIndex, T timestep=0) const
adds this component's non-linear stamp to the target stamp.
void addDCAnalysisStampTo(Stamp< T > &stamp, const Matrix< T > &solutionVector, size_t numCurrents) const
adds this component's DC stamp to the target stamp.
A helper struct to store the preallocated stamps for MNA.