SECircuit.hxx
1/* Distributed under the Apache License, Version 2.0.
2 See accompanying NOTICE file for details.*/
3
4#define ZERO_APPROX 1e-10
5#define OPEN_RESISTANCE 1e100
6
7template<CIRCUIT_TEMPLATE>
8SECircuit<CIRCUIT_TYPES>::SECircuit(const std::string& name, Logger* logger) : Loggable(logger), m_Name(name)
9{
10}
11
12template<CIRCUIT_TEMPLATE>
14{
15 Clear();
16}
17
18template<CIRCUIT_TEMPLATE>
20{
21 for (auto& itr : m_TargetPathMap)
22 delete itr.second;
23 for (auto& itr : m_SourcePathMap)
24 delete itr.second;
25 for (auto& itr : m_ConnectedPathMap)
26 delete itr.second;
27 m_Nodes.clear();
28 m_Paths.clear();
29 m_TargetPathMap.clear();
30 m_SourcePathMap.clear();
31 m_ConnectedPathMap.clear();
32 m_ValvePaths.clear();
33 m_PolarizedElementPaths.clear();
34}
35
36template<CIRCUIT_TEMPLATE>
38{
39 // Cache target and source paths to save lots of time later
40 for (auto& itr : m_TargetPathMap)
41 delete itr.second;
42 for (auto& itr : m_SourcePathMap)
43 delete itr.second;
44 for (auto& itr : m_ConnectedPathMap)
45 delete itr.second;
46 m_TargetPathMap.clear();
47 m_SourcePathMap.clear();
48 m_ConnectedPathMap.clear();
49 m_ValvePaths.clear();
50 m_PolarizedElementPaths.clear();
51
52 for (PathType* p : m_Paths)
53 {
54 if (!p->HasValidElements())
55 {
56 m_ss << p->GetName() << " has invalid elements";
57 Fatal(m_ss);
58 }
59
60 //There should never be a NextFlow value set on a path
61 //Flow sources are defined using NextFlowSource
62 /* if (p->HasNextFlux())
63 {
64 m_ss << p->GetName() << " has flux and will be ignored and overwritten. Use a flux source.";
65 Warning(m_ss);
66 }*/
67
68 // Cache what paths are connected to what nodes
69 NodeType* nTgt = &p->GetTargetNode();
70 NodeType* nSrc = &p->GetSourceNode();
71 std::vector<PathType*>* tgtPaths = m_TargetPathMap[nTgt];
72 std::vector<PathType*>* srcPaths = m_SourcePathMap[nSrc];
73 std::vector<PathType*>* conSrcPaths = m_ConnectedPathMap[nSrc];
74 std::vector<PathType*>* conTgtPaths = m_ConnectedPathMap[nTgt];
75 if (tgtPaths == nullptr)
76 {
77 tgtPaths = new std::vector<PathType*>();
78 m_TargetPathMap[nTgt] = tgtPaths;
79 }
80 if (srcPaths == nullptr)
81 {
82 srcPaths = new std::vector<PathType*>();
83 m_SourcePathMap[nSrc] = srcPaths;
84 }
85 if (conTgtPaths == nullptr)
86 {
87 conTgtPaths = new std::vector<PathType*>();
88 m_ConnectedPathMap[nTgt] = conTgtPaths;
89 }
90 if (conSrcPaths == nullptr)
91 {
92 conSrcPaths = new std::vector<PathType*>();
93 m_ConnectedPathMap[nSrc] = conSrcPaths;
94 }
95
96 //Make sure we didn't accidentally define something twice
97 if (std::find(m_ConnectedPathMap[nSrc]->begin(), m_ConnectedPathMap[nSrc]->end(), p) != m_ConnectedPathMap[nSrc]->end() ||
98 std::find(m_ConnectedPathMap[nTgt]->begin(), m_ConnectedPathMap[nTgt]->end(), p) != m_ConnectedPathMap[nTgt]->end())
99 {
100 m_ss << p->GetName() << " is defined multiple times.";
101 Fatal(m_ss);
102 }
103
104 m_TargetPathMap[nTgt]->push_back(p);
105 m_SourcePathMap[nSrc]->push_back(p);
106 m_ConnectedPathMap[nSrc]->push_back(p);
107 m_ConnectedPathMap[nTgt]->push_back(p);
108
109 // Cache Valves
110 if (p->HasNextValve())
111 m_ValvePaths.push_back(p);
112 if (p->HasNextPolarizedState())
113 m_PolarizedElementPaths.push_back(p);
114 }
115
116 // Check blackbox nodes
117 for (NodeType* n : m_Nodes)
118 {
119 if (n->IsBlackBoxMiddle())
120 {
121 auto paths = GetConnectedPaths(*n);
122 if(paths->size() != 2)
123 {
124 Fatal(n->GetName() + " has invalid black box configuration, must have only 2 paths associated");
125 }
126 }
127 }
128
129 if ((m_ValvePaths.size()+m_PolarizedElementPaths.size()) > 64)
130 {
131 Fatal("There are too many assumed state options. The Circuit solver can only handle up to 64 Diodes and Polar Elements in a single circuit (i.e. ~1.8e19 possible combinations).");
132 }
133}
134
135template<CIRCUIT_TEMPLATE>
136std::string SECircuit<CIRCUIT_TYPES>::GetName() const
137{
138 return m_Name;
139}
140
141template<CIRCUIT_TEMPLATE>
143{
144 for (NodeType* n : m_Nodes)
145 {
146 if (n->IsReferenceNode())
147 {
148 return true;
149 }
150 }
151 return false;
152}
153
154template<CIRCUIT_TEMPLATE>
155void SECircuit<CIRCUIT_TYPES>::AddNode(NodeType& node)
156{
157 if (!Contains(this->m_Nodes, node))
158 this->m_Nodes.push_back(&node);
159}
160template<CIRCUIT_TEMPLATE>
162{
163 this->m_Nodes.push_back(&node);
164}
165template<CIRCUIT_TEMPLATE>
166bool SECircuit<CIRCUIT_TYPES>::HasNode(NodeType& node)
167{
168 return Contains(m_Nodes, node);
169}
170template<CIRCUIT_TEMPLATE>
171bool SECircuit<CIRCUIT_TYPES>::HasNode(const std::string& name)
172{
173 return GetNode(name) != nullptr;
174}
175template<CIRCUIT_TEMPLATE>
176NodeType* SECircuit<CIRCUIT_TYPES>::GetNode(const std::string& name)
177{
178 for (NodeType* n : m_Nodes)
179 {
180 if (n->GetName() == name)
181 return n;
182 }
183 return nullptr;
184}
185template<CIRCUIT_TEMPLATE>
186const NodeType* SECircuit<CIRCUIT_TYPES>::GetNode(const std::string& name) const
187{
188 for (NodeType* n : m_Nodes)
189 {
190 if (n->GetName() == name)
191 return n;
192 }
193 return nullptr;
194}
195template<CIRCUIT_TEMPLATE>
196const std::vector<NodeType*>& SECircuit<CIRCUIT_TYPES>::GetNodes() const
197{
198 return m_Nodes;
199}
200template<CIRCUIT_TEMPLATE>
201void SECircuit<CIRCUIT_TYPES>::RemoveNode(const NodeType& node)
202{
203 size_t i = 0;
204 for (NodeType* n : m_Nodes)
205 {
206 if (n == &node)
207 {
208 m_Nodes.erase(m_Nodes.begin() + i);
209 return;
210 }
211 i++;
212 }
213}
214template<CIRCUIT_TEMPLATE>
215void SECircuit<CIRCUIT_TYPES>::RemoveNode(const std::string& name)
216{
217 size_t i = 0;
218 for (NodeType* n : m_Nodes)
219 {
220 if(n->GetName()==name)
221 {
222 m_Nodes.erase(m_Nodes.begin()+i);
223 return;
224 }
225 i++;
226 }
227}
228
229template<CIRCUIT_TEMPLATE>
230void SECircuit<CIRCUIT_TYPES>::AddPath(PathType& path)
231{
232 if (!Contains(m_Paths, path))
233 m_Paths.push_back(&path);
234}
235template<CIRCUIT_TEMPLATE>
237{
238 m_Paths.push_back(&path);
239}
240template<CIRCUIT_TEMPLATE>
241bool SECircuit<CIRCUIT_TYPES>::HasPath(PathType& path)
242{
243 return Contains(m_Paths, path);
244}
245template<CIRCUIT_TEMPLATE>
246bool SECircuit<CIRCUIT_TYPES>::HasPath(const std::string& name)
247{
248 return GetPath(name) != nullptr;
249}
250template<CIRCUIT_TEMPLATE>
251PathType* SECircuit<CIRCUIT_TYPES>::GetPath(const std::string& name)
252{
253 for (PathType* p : m_Paths)
254 {
255 if(p->GetName() == name)
256 return p;
257 }
258 return nullptr;
259}
260template<CIRCUIT_TEMPLATE>
261const PathType* SECircuit<CIRCUIT_TYPES>::GetPath(const std::string& name) const
262{
263 for (PathType* p : m_Paths)
264 {
265 if (p->GetName() == name)
266 return p;
267 }
268 return nullptr;
269}
270template<CIRCUIT_TEMPLATE>
271const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetPaths() const
272{
273 return m_Paths;
274}
275template<CIRCUIT_TEMPLATE>
276void SECircuit<CIRCUIT_TYPES>::RemovePath(const PathType& path)
277{
278 size_t i = 0;
279 for (PathType* p : m_Paths)
280 {
281 if(p==&path)
282 {
283 m_Paths.erase(m_Paths.begin()+i);
284 return;
285 }
286 i++;
287 }
288}
289template<CIRCUIT_TEMPLATE>
290void SECircuit<CIRCUIT_TYPES>::RemovePath(const std::string& name)
291{
292 size_t i = 0;
293 for (PathType* p : m_Paths)
294 {
295 if (p->GetName() == name)
296 {
297 m_Paths.erase(m_Paths.begin() + i);
298 return;
299 }
300 i++;
301 }
302}
303template<CIRCUIT_TEMPLATE>
304const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetValvePaths()
305{
306 return m_ValvePaths;
307}
308template<CIRCUIT_TEMPLATE>
309const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetPolarizedElementPaths()
310{
311 return m_PolarizedElementPaths;
312}
313
314//--------------------------------------------------------------------------------------------------
325//--------------------------------------------------------------------------------------------------
326template<CIRCUIT_TEMPLATE>
327const std::vector<PathType*>* SECircuit<CIRCUIT_TYPES>::GetTargetPaths(const NodeType& node) const
328{
329 auto itr = m_TargetPathMap.find(&node);
330 if (itr == m_TargetPathMap.end())
331 {
332 Error("Circuit does not have path information for node : " + node.GetName());
333 return nullptr;
334 }
335 return itr->second;
336}
337
338//--------------------------------------------------------------------------------------------------
349//--------------------------------------------------------------------------------------------------
350template<CIRCUIT_TEMPLATE>
351const std::vector<PathType*>* SECircuit<CIRCUIT_TYPES>::GetSourcePaths(const NodeType& node) const
352{
353 auto itr = m_SourcePathMap.find(&node);
354 if (itr == m_SourcePathMap.end())
355 {
356 Error("Circuit does not have path information for node : " + node.GetName());
357 return nullptr;
358 }
359 return itr->second;
360}
361
362//--------------------------------------------------------------------------------------------------
373//--------------------------------------------------------------------------------------------------
374template<CIRCUIT_TEMPLATE>
375const std::vector<PathType*>* SECircuit<CIRCUIT_TYPES>::GetConnectedPaths(const NodeType& node) const
376{
377 auto itr = m_ConnectedPathMap.find(&node);
378 if (itr == m_ConnectedPathMap.end())
379 {
380 Error("Circuit does not have path information for node : " + node.GetName());
381 return nullptr;
382 }
383 return itr->second;
384}
385
386//--------------------------------------------------------------------------------------------------
389//--------------------------------------------------------------------------------------------------
390template<CIRCUIT_TEMPLATE>
392{
393 for(PathType* p : m_Paths)
394 {
395 if (p->HasResistanceBaseline())
396 {
397 p->GetResistance().Copy(p->GetResistanceBaseline());
398 p->GetNextResistance().Copy(p->GetResistanceBaseline());
399 }
400
401 if (p->HasCapacitanceBaseline())
402 {
403 p->GetCapacitance().Copy(p->GetCapacitanceBaseline());
404 p->GetNextCapacitance().Copy(p->GetCapacitanceBaseline());
405 }
406
407 if (p->HasInductanceBaseline())
408 {
409 p->GetInductance().Copy(p->GetInductanceBaseline());
410 p->GetNextInductance().Copy(p->GetInductanceBaseline());
411 }
412
413 if (p->HasFluxSourceBaseline())
414 {
415 p->GetFluxSource().Copy(p->GetFluxSourceBaseline());
416 p->GetNextFluxSource().Copy(p->GetFluxSourceBaseline());
417 }
418
419 if (p->HasPotentialSourceBaseline())
420 {
421 p->GetPotentialSource().Copy(p->GetPotentialSourceBaseline());
422 p->GetNextPotentialSource().Copy(p->GetPotentialSourceBaseline());
423 }
424
425 if (p->HasSwitch())
426 p->SetNextSwitch(p->GetSwitch());
427 if (p->HasValve())
428 p->SetNextValve(p->GetValve());
429 }
430
431 for (NodeType* n : m_Nodes)
432 {
433 if (n->HasQuantityBaseline())
434 {
435 n->GetQuantity().Copy(n->GetQuantityBaseline());
436 n->GetNextQuantity().Copy(n->GetQuantityBaseline());
437 }
438 }
439}
440
441#include "cdm/circuit/electrical/SEElectricalCircuit.h"
443#include "cdm/circuit/fluid/SEFluidCircuit.h"
445#include "cdm/circuit/thermal/SEThermalCircuit.h"
Definition: Logger.h:23
Definition: Logger.h:71
virtual const std::vector< PathType * > & GetValvePaths()
Definition: SECircuit.cpp:307
virtual const std::vector< PathType * > * GetSourcePaths(const NodeType &node) const
Returns all source paths for a node.
Definition: SECircuit.cpp:354
virtual void RemoveNode(const NodeType &node)
Definition: SECircuit.cpp:204
virtual std::string GetName() const
Definition: SECircuit.cpp:139
virtual void RemovePath(const PathType &path)
Definition: SECircuit.cpp:279
virtual void AddPath(PathType &node)
Definition: SECircuit.cpp:233
virtual const std::vector< PathType * > * GetTargetPaths(const NodeType &node) const
Returns all target paths for a node.
Definition: SECircuit.cpp:330
virtual bool HasPath(PathType &node)
Definition: SECircuit.cpp:244
virtual void AddNode(NodeType &node)
Definition: SECircuit.cpp:158
virtual const std::vector< PathType * > * GetConnectedPaths(const NodeType &node) const
Returns all source paths for a node.
Definition: SECircuit.cpp:378
virtual ~SECircuit()
Definition: SECircuit.cpp:16
SECircuit(const std::string &name, Logger *logger)
Definition: SECircuit.cpp:11
virtual NodeType * GetNode(const std::string &name)
Definition: SECircuit.cpp:179
virtual void ForceAddNode(NodeType &node)
Definition: SECircuit.cpp:164
virtual void ForceAddPath(PathType &node)
Definition: SECircuit.cpp:239
virtual void SetNextAndCurrentFromBaselines()
Set all Current and Next values to the Baseline values for all Elements.
Definition: SECircuit.cpp:394
virtual bool HasNode(NodeType &node)
Definition: SECircuit.cpp:169
virtual bool HasReferenceNode() const
Definition: SECircuit.cpp:145
virtual const std::vector< NodeType * > & GetNodes() const
Definition: SECircuit.cpp:199
virtual const std::vector< PathType * > & GetPaths() const
Definition: SECircuit.cpp:274
virtual void Clear()
Definition: SECircuit.cpp:22
virtual PathType * GetPath(const std::string &name)
Definition: SECircuit.cpp:254
virtual void StateChange()
Definition: SECircuit.cpp:40
virtual const std::vector< PathType * > & GetPolarizedElementPaths()
Definition: SECircuit.cpp:312

Distributed under the Apache License, Version 2.0.

See accompanying NOTICE file for details.