JUK1
TimeSeriesVoltageSource.hpp
Go to the documentation of this file.
1 #ifndef _TIMESERIESVOLTAGESOURCE_INC_
2 #define _TIMESERIESVOLTAGESOURCE_INC_
5 #include <math.h>
6 
10 template<typename T>
11 struct TimeSeriesVoltageSource : public Component<T> {
12  size_t n1 = 0;
13  size_t n2 = 0;
14  size_t currentIndex = 0;
15  size_t lastTimeSeriesIndex = 0;
16 
17  std::vector<T> timeSeries;
18  std::vector<T> dataSeries;
19 
20  T lerp(size_t lowIndex, T timeVal) const {
21  T diffTS = timeSeries[(lowIndex + 1) % timeSeries.size()] -
22  timeSeries[lowIndex];
23  T diffTV = timeVal - timeSeries[lowIndex];
24  T diffDS = dataSeries[(lowIndex + 1) % timeSeries.size()] -
25  dataSeries[lowIndex];
26  return dataSeries[lowIndex] + diffDS * diffTV / diffTS;
27  }
28 
29  void addDynamicStampTo(Stamp<T> & stamp, const Matrix<T> & solutionMatrix,
30  const size_t currentSolutionIndex, T timestep) const {
31  size_t n1p = n1 - 1;
32  size_t n2p = n2 - 1;
33  size_t currentIndexp = currentIndex - 1;
34  size_t timeSeriesIndex = lastTimeSeriesIndex;
35  T timeMod = std::fmod(currentSolutionIndex * timestep, timeSeries.back());
36  while (timeMod > timeSeries[(timeSeriesIndex + 1) % timeSeries.size()] ||
37  (timeSeriesIndex != 0 &&
38  timeMod < timeSeries[(timeSeriesIndex - 1) % timeSeries.size()])) {
39  timeSeriesIndex = (timeSeriesIndex + 1) % timeSeries.size();
40  }
41 
42  if (n1) {
43  stamp.G(n1p, stamp.sizeG_A + currentIndexp) += 1;
44  stamp.G(stamp.sizeG_A + currentIndexp, n1p) += 1;
45  }
46 
47  if (n2) {
48  stamp.G(n2p, stamp.sizeG_A + currentIndexp) += -1;
49  stamp.G(stamp.sizeG_A + currentIndexp, n2p) += -1;
50  }
51 
52  stamp.s(stamp.sizeG_A + currentIndexp, 0) += lerp(timeSeriesIndex, timeMod);
53  }
54 
55  void updateStoredState(const Matrix<T> & solutionMatrix,
56  const size_t currentSolutionIndex, T timestep,
57  size_t sizeG_A) {
58  while (std::fmod(currentSolutionIndex * timestep, timeSeries.back()) >
59  timeSeries[(lastTimeSeriesIndex + 1) % timeSeries.size()] ||
60  (lastTimeSeriesIndex != 0 &&
61  std::fmod(currentSolutionIndex * timestep, timeSeries.back()) <
62  timeSeries[(lastTimeSeriesIndex - 1) % timeSeries.size()])) {
64  }
65  }
66 
67  void addDCAnalysisStampTo(Stamp<T> & stamp, const Matrix<T> & solutionVector,
68  size_t numCurrents) const {
69  addDynamicStampTo(stamp, solutionVector, 0, 0);
70  }
71 
72  static void
73  addToElements(const std::string & line, CircuitElements<T> & elements,
74  size_t & numNodes, size_t & numCurrents, size_t & numDCCurrents) {
75  // n1 n2 timescale file
76  std::regex timeSeriesVoltageSourceRegex = generateRegex("VT", "n n w s",
77  true, false);
78 
79  TimeSeriesVoltageSource<T> voltageSource;
80  std::smatch matches;
81 
82  std::regex_search(line, matches, timeSeriesVoltageSourceRegex);
83 
84  voltageSource.designator = "VT";
85  voltageSource.designator += matches.str(1);
86 
87  voltageSource.n1 = std::stoi(matches.str(2));
88  voltageSource.n2 = std::stoi(matches.str(3));
89 
90  numNodes = std::max(numNodes, std::stoull(matches.str(2)));
91  numNodes = std::max(numNodes, std::stoull(matches.str(3)));
92 
93  T timescale = 0;
94  if constexpr (std::is_same_v<T, double> || std::is_same_v<T, float>) {
95  timescale = std::stod(matches.str(4));
96  } else {
97  static_assert("Unsupported Type");
98  }
99 
100 
101  voltageSource.currentIndex = ++numCurrents;
102 
103  std::regex endOfLineRegex(R"(^(.*)$)");
104  std::regex_search(matches.suffix().first, line.cend(), matches,
105  endOfLineRegex);
106 
107  std::string seriesPath = matches.str(1);
108  voltageSource.readInTimeSeries(timescale, seriesPath);
109 
110  elements.dynamicElements.emplace_back(
111  std::make_shared<TimeSeriesVoltageSource<T> >(voltageSource));
112  elements.nodeComponentMap.insert(
113  {{voltageSource.n1, elements.dynamicElements.back()},
114  {voltageSource.n2, elements.dynamicElements.back()}});
115  }
116 
117  void readInTimeSeries(T timescale, const std::string & seriesPath) {
118  std::ifstream file(seriesPath);
119 
120  std::string line;
121  T time;
122  T val;
123 
124  while (!file.eof()) {
125  if (!std::isdigit(file.peek())) {
126  std::getline(file, line);
127  continue;
128  }
129 
130  file >> time;
131 
132  while (!std::isdigit(file.peek()) &&
133  !(file.peek() == '-' || file.peek() == '+')) {
134  file.ignore(1);
135  }
136 
137  file >> val;
138 
139  timeSeries.emplace_back(time * timescale);
140  dataSeries.emplace_back(val);
141  }
142  }
143 };
144 
145 #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
if d time
Definition: comp.m:6
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 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
A time series voltage source model.
T lerp(size_t lowIndex, T timeVal) const
void readInTimeSeries(T timescale, const std::string &seriesPath)
void addDCAnalysisStampTo(Stamp< T > &stamp, const Matrix< T > &solutionVector, size_t numCurrents) const
adds this component's DC stamp to the target stamp.
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.
static void addToElements(const std::string &line, CircuitElements< T > &elements, size_t &numNodes, size_t &numCurrents, size_t &numDCCurrents)
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.