JUK1
Inductor.hpp
Go to the documentation of this file.
1 #ifndef _INDUCTOR_HPP_INC_
2 #define _INDUCTOR_HPP_INC_
5 
6 
10 template<typename T>
11 struct Inductor : public Component<T> {
12  public:
13  T value = 0;
14 
15  size_t n1 = 0;
16  size_t n2 = 0;
17  T lastCurrent = 0;
18 
19  size_t dcCurrentIndex = 0;
20 
21  bool trapezoidalRule = true;
22  void addDynamicStampTo(Stamp<T> & stamp, const Matrix<T> & solutionMatrix,
23  const size_t currentSolutionIndex, T timestep) const {
24  size_t n1p = n1 - 1;
25  size_t n2p = n2 - 1;
26 
27  T u0 = 0;
28  if (n1) {
29  u0 = solutionMatrix(n1p, currentSolutionIndex - 1);
30  }
31 
32  if (n2) {
33  u0 -= solutionMatrix(n2p, currentSolutionIndex - 1);
34  }
35 
36 
37  T G_eq = 0;
38  T I_eq = 0;
39 
40  if (trapezoidalRule) {
41  G_eq = timestep / (2 * value);
42  I_eq = lastCurrent + G_eq * u0;
43  } else {
44  G_eq = timestep / timestep;
45  I_eq = lastCurrent;
46  }
47 
48  if (n1) {
49  stamp.G(n1p, n1p) += G_eq;
50  stamp.s(n1p, 0) += -I_eq;
51  }
52 
53  if (n2) {
54  stamp.G(n2p, n2p) += G_eq;
55  stamp.s(n2p, 0) += I_eq;
56  }
57 
58  if (n1 && n2) {
59  stamp.G(n1p, n2p) += -G_eq;
60  stamp.G(n2p, n1p) += -G_eq;
61  }
62  }
63 
64  void updateStoredState(const Matrix<T> & solutionMatrix,
65  const size_t currentSolutionIndex, T timestep,
66  size_t sizeG_A) {
67  size_t n1p = n1 - 1;
68  size_t n2p = n2 - 1;
69  T u0 = 0;
70  T u1 = 0;
71  if (n1) {
72  u0 = solutionMatrix(n1p, currentSolutionIndex - 1);
73  u1 = solutionMatrix(n1p, currentSolutionIndex);
74  }
75 
76  if (n2) {
77  u0 -= solutionMatrix(n2p, currentSolutionIndex - 1);
78  u1 -= solutionMatrix(n2p, currentSolutionIndex);
79  }
80 
81  if (trapezoidalRule) {
82  T G_eq = timestep / (2 * value);
83  lastCurrent = G_eq * u1 + (lastCurrent + G_eq * u0);
84  } else {
85  T G_eq = timestep / value;
86  lastCurrent = G_eq * u1 + lastCurrent;
87  }
88  }
89 
90  void updateDCStoredState(const Matrix<T> & solutionVector, size_t sizeG_A,
91  size_t numCurrents) {
92  lastCurrent = solutionVector(sizeG_A + numCurrents + dcCurrentIndex - 1, 0);
93  }
94 
95  void addDCAnalysisStampTo(Stamp<T> & stamp, const Matrix<T> & solutionVector,
96  size_t numCurrents) const {
97  // Short circuit
98  size_t n1p = n1 - 1;
99  size_t n2p = n2 - 1;
100  size_t dcCurrentIndexp = dcCurrentIndex - 1;
101 
102  if (n1 > 0) {
103  stamp.G(n1p, stamp.sizeG_A + numCurrents + dcCurrentIndexp) += 1;
104  stamp.G(stamp.sizeG_A + numCurrents + dcCurrentIndexp, n1p) += 1;
105  }
106 
107  if (n2 > 0) {
108  stamp.G(n2p, stamp.sizeG_A + numCurrents + dcCurrentIndexp) += -1;
109  stamp.G(stamp.sizeG_A + numCurrents + dcCurrentIndexp, n2p) += -1;
110  }
111  }
112 
113  static void
114  addToElements(const std::string & line, CircuitElements<T> & elements,
115  size_t & numNodes, size_t & numCurrents, size_t & numDCCurrents) {
116  // std::regex inductorRegex( R"(^L(.*?)\s(\d+?)\s(\d+?)\s(.+?)\s?$)" );
117  std::regex inductorRegex = generateRegex("L", "n n w");
118  Inductor<T> inductor;
119  std::smatch matches;
120 
121  std::regex_match(line, matches, inductorRegex);
122 
123  inductor.designator = "L";
124  inductor.designator += matches.str(1);
125 
126  inductor.n1 = std::stoi(matches.str(2));
127  inductor.n2 = std::stoi(matches.str(3));
128  inductor.trapezoidalRule = true;
129  inductor.dcCurrentIndex = ++numDCCurrents;
130 
131  numNodes = std::max(numNodes, std::stoull(matches.str(2)));
132  numNodes = std::max(numNodes, std::stoull(matches.str(3)));
133 
134  if constexpr (std::is_same_v<T, double> || std::is_same_v<T, float>) {
135  inductor.value = std::stod(matches.str(4));
136  } else {
137  static_assert("Unsupported Type");
138  }
139 
140  elements.dynamicElements.emplace_back(
141  std::make_shared<Inductor<T> >(inductor));
142 
143  elements.nodeComponentMap.insert(
144  {{inductor.n1, elements.dynamicElements.back()},
145  {inductor.n2, elements.dynamicElements.back()}});
146  }
147 };
148 
149 #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
An ideal inductor model.
Definition: Inductor.hpp:11
size_t n2
Definition: Inductor.hpp:16
static void addToElements(const std::string &line, CircuitElements< T > &elements, size_t &numNodes, size_t &numCurrents, size_t &numDCCurrents)
Definition: Inductor.hpp:114
T lastCurrent
Definition: Inductor.hpp:17
size_t n1
Definition: Inductor.hpp:15
void addDCAnalysisStampTo(Stamp< T > &stamp, const Matrix< T > &solutionVector, size_t numCurrents) const
adds this component's DC stamp to the target stamp.
Definition: Inductor.hpp:95
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: Inductor.hpp:64
size_t dcCurrentIndex
Definition: Inductor.hpp:19
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: Inductor.hpp:90
void addDynamicStampTo(Stamp< T > &stamp, const Matrix< T > &solutionMatrix, const size_t currentSolutionIndex, T timestep) const
Adds this component's dynamic stamp to the target stamp.
Definition: Inductor.hpp:22
bool trapezoidalRule
Definition: Inductor.hpp:21
A matrix class with support for LU-decomposition, and left division.
A helper struct to store the preallocated stamps for MNA.
Definition: Component.hpp:23
Matrix< T > s
Definition: Component.hpp:28
size_t sizeG_A
Definition: Component.hpp:24
Matrix< T > G
Definition: Component.hpp:27