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 
7 template<CIRCUIT_TEMPLATE>
8 SECircuit<CIRCUIT_TYPES>::SECircuit(const std::string& name, Logger* logger) : Loggable(logger), m_Name(name)
9 {
10 }
11 
12 template<CIRCUIT_TEMPLATE>
14 {
15  Clear();
16 }
17 
18 template<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 
36 template<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 
135 template<CIRCUIT_TEMPLATE>
136 std::string SECircuit<CIRCUIT_TYPES>::GetName() const
137 {
138  return m_Name;
139 }
140 
141 template<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 
154 template<CIRCUIT_TEMPLATE>
155 void SECircuit<CIRCUIT_TYPES>::AddNode(NodeType& node)
156 {
157  if (!Contains(this->m_Nodes, node))
158  this->m_Nodes.push_back(&node);
159 }
160 template<CIRCUIT_TEMPLATE>
161 void SECircuit<CIRCUIT_TYPES>::ForceAddNode(NodeType& node)
162 {
163  this->m_Nodes.push_back(&node);
164 }
165 template<CIRCUIT_TEMPLATE>
166 bool SECircuit<CIRCUIT_TYPES>::HasNode(NodeType& node)
167 {
168  return Contains(m_Nodes, node);
169 }
170 template<CIRCUIT_TEMPLATE>
171 bool SECircuit<CIRCUIT_TYPES>::HasNode(const std::string& name)
172 {
173  return GetNode(name) != nullptr;
174 }
175 template<CIRCUIT_TEMPLATE>
176 NodeType* 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 }
185 template<CIRCUIT_TEMPLATE>
186 const 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 }
195 template<CIRCUIT_TEMPLATE>
196 const std::vector<NodeType*>& SECircuit<CIRCUIT_TYPES>::GetNodes() const
197 {
198  return m_Nodes;
199 }
200 template<CIRCUIT_TEMPLATE>
201 void 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 }
214 template<CIRCUIT_TEMPLATE>
215 void 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 
229 template<CIRCUIT_TEMPLATE>
230 void SECircuit<CIRCUIT_TYPES>::AddPath(PathType& path)
231 {
232  if (!Contains(m_Paths, path))
233  m_Paths.push_back(&path);
234 }
235 template<CIRCUIT_TEMPLATE>
236 void SECircuit<CIRCUIT_TYPES>::ForceAddPath(PathType& path)
237 {
238  m_Paths.push_back(&path);
239 }
240 template<CIRCUIT_TEMPLATE>
241 bool SECircuit<CIRCUIT_TYPES>::HasPath(PathType& path)
242 {
243  return Contains(m_Paths, path);
244 }
245 template<CIRCUIT_TEMPLATE>
246 bool SECircuit<CIRCUIT_TYPES>::HasPath(const std::string& name)
247 {
248  return GetPath(name) != nullptr;
249 }
250 template<CIRCUIT_TEMPLATE>
251 PathType* 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 }
260 template<CIRCUIT_TEMPLATE>
261 const 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 }
270 template<CIRCUIT_TEMPLATE>
271 const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetPaths() const
272 {
273  return m_Paths;
274 }
275 template<CIRCUIT_TEMPLATE>
276 void 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 }
289 template<CIRCUIT_TEMPLATE>
290 void 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 }
303 template<CIRCUIT_TEMPLATE>
304 const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetValvePaths()
305 {
306  return m_ValvePaths;
307 }
308 template<CIRCUIT_TEMPLATE>
309 const std::vector<PathType*>& SECircuit<CIRCUIT_TYPES>::GetPolarizedElementPaths()
310 {
311  return m_PolarizedElementPaths;
312 }
313 
314 //--------------------------------------------------------------------------------------------------
325 //--------------------------------------------------------------------------------------------------
326 template<CIRCUIT_TEMPLATE>
327 const 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 //--------------------------------------------------------------------------------------------------
350 template<CIRCUIT_TEMPLATE>
351 const 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 //--------------------------------------------------------------------------------------------------
374 template<CIRCUIT_TEMPLATE>
375 const 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 //--------------------------------------------------------------------------------------------------
390 template<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.