JUK1
NLNMOS.hpp
Go to the documentation of this file.
1 #ifndef _NLNMOS_HPP_INC_
2 #define _NLNMOS_HPP_INC_
5 #include <math.h>
6 
9 template<typename T>
10 struct NLNMOS : public Component<T> {
11  public:
12  size_t d = 0;
13  size_t g = 0;
14  size_t s = 0;
15 
16  // constant params of the model
17  const T C_GSp = 0.01;
18  const T C_GSo = 0.5;
19  const T P_S10 = 0;
20  const T P_S11 = 0.5;
21  const T C_GDp = 0.5;
22  const T C_GDo = 1;
23  const T P_D10 = -1;
24  const T P_D11 = 0.4;
25 
26  const T beta_DS = 1.3;
27  const T alpha_DS = 0.42;
28 
29  T u_gd_last = 0;
30  T u_gs_last = 0;
31 
32 
33  T i_gd_last = 0;
34  T i_gs_last = 0;
35 
36  T C_GD_last = C_GDp + C_GDo * (1.0 + std::tanh(P_D10 + P_D11 * u_gd_last));
37  T C_GS_last = C_GSp + C_GSo * (1.0 + std::tanh(P_S10 + P_S11 * u_gs_last));
38 
39  void
40  addNonLinearStampTo(Stamp<T> & stamp, const Matrix<T> & solutionMatrix,
41  const size_t currentSolutionIndex, T timestep = 0) const {
42  const size_t gp = g - 1;
43  const size_t dp = d - 1;
44  const size_t sp = s - 1;
45 
46  T u_gs = 0;
47  T u_gd = 0;
48 
49  if (g > 0) {
50  u_gs = solutionMatrix(gp, currentSolutionIndex);
51  u_gd = solutionMatrix(gp, currentSolutionIndex);
52  }
53 
54  if (s > 0) {
55  u_gs -= solutionMatrix(sp, currentSolutionIndex);
56  }
57 
58  if (d > 0) {
59  u_gd -= solutionMatrix(dp, currentSolutionIndex);
60  }
61 
62  T C_GD = C_GDp + C_GDo * (1.0 + std::tanh(P_D10 + P_D11 * u_gd));
63  T C_GS = C_GSp + C_GSo * (1.0 + std::tanh(P_S10 + P_S11 * u_gs));
64 
65  T dC_GD = C_GDo * P_D11 / std::pow(std::cosh(P_D10 + P_D11 * u_gd), 2);
66  T dC_GS = C_GSo * P_S11 / std::pow(std::cosh(P_S10 + P_S11 * u_gs), 2);
67 
68  T i_ds = beta_DS * std::tanh(alpha_DS * (u_gs - u_gd));
69  T di_ds_d = -beta_DS * alpha_DS /
70  std::pow(std::cosh(alpha_DS * (u_gs - u_gd)), 2);
71  T di_ds_s = beta_DS * alpha_DS /
72  std::pow(std::cosh(alpha_DS * (u_gs - u_gd)), 2);
73 
74  T i_gd = C_GD *
75  (2.0 * (u_gd - u_gd_last) / timestep - i_gd_last / C_GD_last);
76  T i_gs = C_GS *
77  (2.0 * (u_gs - u_gs_last) / timestep - i_gs_last / C_GS_last);
78 
79  T i_d = -i_gd + i_ds;
80  T i_s = -i_gs - i_ds;
81  T i_g = i_gs + i_gd;
82 
83  T di_gd = dC_GD *
84  (2.0 * (u_gd - u_gd_last) / timestep - i_gd_last / C_GD_last) +
85  2.0 * C_GD / timestep;
86  T di_gs = dC_GS *
87  (2.0 * (u_gs - u_gs_last) / timestep - i_gs_last / C_GS_last) +
88  2.0 * C_GS / timestep;
89 
90  T g_dd = -di_gd + di_ds_d;
91  T g_sd = -di_ds_d;
92  T g_gd = di_gd;
93 
94  T g_ds = di_ds_d;
95  T g_ss = -di_gs - di_ds_s;
96  T g_gs = di_gs;
97 
98  T I_d = i_d - g_dd * u_gd - g_ds * u_gs;
99  T I_s = i_s - g_sd * u_gd - g_ss * u_gs;
100  T I_g = i_g - g_gd * u_gd - g_gs * u_gs;
101 
102  if (d > 0) {
103  stamp.G(dp, dp) += -g_dd;
104  stamp.s(dp, 0) += -I_d;
105 
106  if (s > 0) {
107  stamp.G(dp, sp) += -g_ds;
108  }
109 
110  if (g > 0) {
111  stamp.G(dp, gp) += g_dd + g_ds;
112  }
113  }
114 
115  if (s > 0) {
116  stamp.G(sp, sp) += -g_ss;
117  stamp.s(sp, 0) += -I_s;
118 
119  if (d > 0) {
120  stamp.G(sp, dp) += -g_sd;
121  }
122 
123  if (g > 0) {
124  stamp.G(sp, gp) += g_sd + g_ss;
125  }
126  }
127 
128  if (g > 0) {
129  stamp.G(gp, gp) += g_gd + g_gs;
130  stamp.s(gp, 0) += -I_g;
131 
132  if (d > 0) {
133  stamp.G(gp, dp) += -g_gd;
134  }
135 
136  if (s > 0) {
137  stamp.G(gp, sp) += -g_gs;
138  }
139  }
140  }
141 
142  void updateStoredState(const Matrix<T> & solutionMatrix,
143  const size_t currentSolutionIndex, T timestep,
144  size_t sizeG_A) {
145  const size_t gp = g - 1;
146  const size_t dp = d - 1;
147  const size_t sp = s - 1;
148 
149  T u_gs = 0;
150  T u_gd = 0;
151 
152  if (g > 0) {
153  u_gs = solutionMatrix(gp, currentSolutionIndex);
154  u_gd = solutionMatrix(gp, currentSolutionIndex);
155  }
156 
157  if (s > 0) {
158  u_gs -= solutionMatrix(sp, currentSolutionIndex);
159  }
160 
161  if (d > 0) {
162  u_gd -= solutionMatrix(dp, currentSolutionIndex);
163  }
164 
165  T C_GD = C_GDp + C_GDo * (1.0 + std::tanh(P_D10 + P_D11 * u_gd));
166  T C_GS = C_GSp + C_GSo * (1.0 + std::tanh(P_S10 + P_S11 * u_gs));
167 
168  i_gd_last = C_GD *
169  (2.0 * (u_gd - u_gd_last) / timestep - i_gd_last / C_GD_last);
170  i_gs_last = C_GS *
171  (2.0 * (u_gs - u_gs_last) / timestep - i_gs_last / C_GS_last);
172 
173  C_GD_last = C_GD;
174  C_GS_last = C_GS;
175 
176  u_gd_last = u_gd;
177  u_gs_last = u_gs;
178  }
179 
180  static void
181  addToElements(const std::string & line, CircuitElements<T> & elements,
182  size_t & numNodes, size_t & numCurrents, size_t & numDCCurrents) {
183  std::regex BJTRegex = generateRegex("QMN", "n n n");
184  NLNMOS<T> nmos;
185  std::smatch matches;
186 
187  std::regex_match(line, matches, BJTRegex);
188 
189  nmos.designator = "QMN";
190  nmos.designator += matches.str(1);
191 
192  nmos.d = std::stoi(matches.str(2));
193  nmos.g = std::stoi(matches.str(3));
194  nmos.s = std::stoi(matches.str(4));
195 
196  numNodes = std::max(numNodes, std::stoull(matches.str(2)));
197  numNodes = std::max(numNodes, std::stoull(matches.str(3)));
198  numNodes = std::max(numNodes, std::stoull(matches.str(4)));
199 
200 
201  elements.nonLinearElements.emplace_back(std::make_shared<NLNMOS<T> >(nmos));
202  elements.nodeComponentMap.insert(
203  {{nmos.d, elements.nonLinearElements.back()},
204  {nmos.g, elements.nonLinearElements.back()},
205  {nmos.s, elements.nonLinearElements.back()}});
206  }
207 };
208 #endif
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
Definition: QPpassive.m:47
a glorified container for the different types of components.
A template base class to define the fundamental things a component should define.
Definition: Component.hpp:108
std::string designator
The designator as in the netlist for e.g.
Definition: Component.hpp:110
A matrix class with support for LU-decomposition, and left division.
a non-linear FET model
Definition: NLNMOS.hpp:10
T C_GS_last
Definition: NLNMOS.hpp:37
const T P_D10
Definition: NLNMOS.hpp:23
T i_gs_last
Definition: NLNMOS.hpp:34
T C_GD_last
Definition: NLNMOS.hpp:36
size_t s
Definition: NLNMOS.hpp:14
T u_gd_last
Definition: NLNMOS.hpp:29
const T C_GDo
Definition: NLNMOS.hpp:22
const T C_GSo
Definition: NLNMOS.hpp:18
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.
Definition: NLNMOS.hpp:40
size_t d
Definition: NLNMOS.hpp:12
const T alpha_DS
Definition: NLNMOS.hpp:27
const T C_GSp
Definition: NLNMOS.hpp:17
void updateStoredState(const Matrix< T > &solutionMatrix, const size_t currentSolutionIndex, T timestep, size_t sizeG_A)
Updates any stored state based on the current solution index.
Definition: NLNMOS.hpp:142
const T P_S11
Definition: NLNMOS.hpp:20
const T P_D11
Definition: NLNMOS.hpp:24
T u_gs_last
Definition: NLNMOS.hpp:30
size_t g
Definition: NLNMOS.hpp:13
const T beta_DS
Definition: NLNMOS.hpp:26
const T C_GDp
Definition: NLNMOS.hpp:21
static void addToElements(const std::string &line, CircuitElements< T > &elements, size_t &numNodes, size_t &numCurrents, size_t &numDCCurrents)
Definition: NLNMOS.hpp:181
const T P_S10
Definition: NLNMOS.hpp:19
T i_gd_last
Definition: NLNMOS.hpp:33
A helper struct to store the preallocated stamps for MNA.
Definition: Component.hpp:23
Matrix< T > s
Definition: Component.hpp:28
Matrix< T > G
Definition: Component.hpp:27