JUK1
NLCapacitor.hpp
Go to the documentation of this file.
1 #ifndef _NLCAPACITOR_HPP_INC_
2 #define _NLCAPACITOR_HPP_INC_
5 #include <math.h>
6 
10 template<typename T>
11 struct NLCapacitor : public Component<T> {
12  public:
13  size_t n1 = 0;
14  size_t n2 = 0;
15 
16  T C_p = 0;
17  T C_o = 0;
18  T P_10 = 0;
19  T P_11 = 0;
20 
21  T u_last = 0;
22  T i_last = 0;
23 
24  T C_last = C_p + C_o * (1.0 + std::tanh(P_10 + P_11 * u_last));
25 
26  void
27  addNonLinearStampTo(Stamp<T> & stamp, const Matrix<T> & solutionMatrix,
28  const size_t currentSolutionIndex, T timestep = 0) const {
29  const size_t n1p = n1 - 1;
30  const size_t n2p = n2 - 1;
31 
32  T u = 0;
33 
34  if (n1 > 0) {
35  u = solutionMatrix(n1p, currentSolutionIndex);
36  }
37 
38  if (n2 > 0) {
39  u -= solutionMatrix(n2p, currentSolutionIndex);
40  }
41 
42  T C = C_p + C_o * (1.0 + std::tanh(P_10 + P_11 * u));
43 
44  T dC = C_o * P_11 / std::pow(std::cosh(P_10 + P_11 * u), 2);
45 
46  T i = C * (2.0 * (u - u_last) / timestep - i_last / C_last);
47 
48  T di = dC * (2.0 * (u - u_last) / timestep - i_last / C_last) +
49  2.0 * C / timestep;
50 
51  T G_eq = di;
52 
53  T I_eq = -G_eq * u + i;
54 
55  if (n1 > 0) {
56  stamp.G(n1p, n1p) += G_eq;
57  stamp.s(n1p, 0) += -I_eq;
58 
59  if (n2 > 0) {
60  stamp.G(n1p, n2p) += -G_eq;
61  }
62  }
63 
64  if (n2 > 0) {
65  stamp.G(n2p, n2p) += G_eq;
66  stamp.s(n2p, 0) += +I_eq;
67 
68  if (n1 > 0) {
69  stamp.G(n2p, n1p) += -G_eq;
70  }
71  }
72  }
73 
74  void updateStoredState(const Matrix<T> & solutionMatrix,
75  const size_t currentSolutionIndex, T timestep,
76  size_t sizeG_A) {
77  const size_t n1p = n1 - 1;
78  const size_t n2p = n2 - 1;
79 
80  T u = 0;
81 
82  if (n1 > 0) {
83  u = solutionMatrix(n1p, currentSolutionIndex);
84  }
85 
86  if (n2 > 0) {
87  u -= solutionMatrix(n2p, currentSolutionIndex);
88  }
89 
90  T C = C_p + C_o * (1.0 + std::tanh(P_10 + P_11 * u));
91 
92  i_last = C * (2.0 * (u - u_last) / timestep - i_last / C_last);
93 
94  C_last = C;
95 
96  u_last = u;
97  }
98 
99  void updateDCStoredState(const Matrix<T> & solutionVector, size_t sizeG_A,
100  size_t numCurrents) {
101  const size_t n1p = n1 - 1;
102  const size_t n2p = n2 - 1;
103 
104  T u = 0;
105 
106  if (n1 > 0) {
107  u = solutionVector(n1p, 0);
108  }
109 
110  if (n2 > 0) {
111  u -= solutionVector(n2p, 0);
112  }
113 
114  T C = C_p + C_o * (1.0 + std::tanh(P_10 + P_11 * u));
115 
116  i_last = 0;
117 
118  C_last = C;
119 
120  u_last = u;
121  }
122 
123  void addDCAnalysisStampTo(Stamp<T> & stamp, const Matrix<T> & solutionVector,
124  size_t numCurrents) const {
125  // open circuit
126  if (n1 > 0) {
127  stamp.G(n1 - 1, n1 - 1) += 1e-9;
128  }
129  if (n2 > 0) {
130  stamp.G(n2 - 1, n2 - 1) += 1e-9;
131  }
132  }
133 
134  static void
135  addToElements(const std::string & line, CircuitElements<T> & elements,
136  size_t & numNodes, size_t & numCurrents, size_t & numDCCurrents) {
137  std::regex capacitorRegex = generateRegex("CN", "n n w w w w");
138  NLCapacitor<T> cap;
139  std::smatch matches;
140 
141  std::regex_match(line, matches, capacitorRegex);
142 
143  cap.designator = "CN";
144  cap.designator += matches.str(1);
145 
146  cap.n1 = std::stoi(matches.str(2));
147  cap.n2 = std::stoi(matches.str(3));
148 
149  numNodes = std::max(numNodes, std::stoull(matches.str(2)));
150  numNodes = std::max(numNodes, std::stoull(matches.str(3)));
151 
152  if constexpr (std::is_same_v<T, double> || std::is_same_v<T, float>) {
153  cap.C_p = std::stod(matches.str(4));
154  cap.C_o = std::stod(matches.str(5));
155  cap.P_10 = std::stod(matches.str(6));
156  cap.P_11 = std::stod(matches.str(7));
157  cap.C_last = cap.C_p +
158  cap.C_o *
159  (1.0 + std::tanh(cap.P_10 + cap.P_11 * cap.u_last));
160  } else {
161  static_assert("Unsupported Type");
162  }
163 
164 
165  elements.nonLinearElements.emplace_back(
166  std::make_shared<NLCapacitor<T> >(cap));
167  elements.nodeComponentMap.insert(
168  {{cap.n1, elements.nonLinearElements.back()},
169  {cap.n2, elements.nonLinearElements.back()}});
170  }
171 };
172 #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
for i
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 capacitor model of the form C = C_p + C_o * ( 1.0 + tanh( P_10 + P_11 * u ) )
Definition: NLCapacitor.hpp:11
void addDCAnalysisStampTo(Stamp< T > &stamp, const Matrix< T > &solutionVector, size_t numCurrents) const
adds this component's DC stamp to the target stamp.
void updateDCStoredState(const Matrix< T > &solutionVector, size_t sizeG_A, size_t numCurrents)
a function to update the stored state of a component based on a DC value
Definition: NLCapacitor.hpp:99
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: NLCapacitor.hpp:27
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: NLCapacitor.hpp:74
static void addToElements(const std::string &line, CircuitElements< T > &elements, size_t &numNodes, size_t &numCurrents, size_t &numDCCurrents)
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