DPsim
DataLoggerInterface.h
1 /* An interface for data loggers for simulation data
2  * logging.
3  *
4  * Author: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
5  * SPDX-FileCopyrightText: 2024 Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #pragma once
9 
10 #include <dpsim-models/Attribute.h>
11 #include <dpsim-models/Filesystem.h>
12 #include <dpsim-models/PtrFactory.h>
13 #include <dpsim-models/SimNode.h>
14 #include <dpsim-models/Task.h>
15 #include <dpsim/Definitions.h>
16 #include <dpsim/Scheduler.h>
17 #include <iomanip>
18 
19 namespace DPsim {
20 
22 protected:
23  std::map<String, CPS::AttributeBase::Ptr> mAttributes;
24 
25 public:
26  typedef std::shared_ptr<DataLoggerInterface> Ptr;
27  typedef std::vector<DataLoggerInterface::Ptr> List;
28 
29  DataLoggerInterface() : mAttributes(){};
30 
31  // Start the logger. After starting the number of columns should not be changed.
32  virtual void start() = 0;
33  // Stops the logger. Afterwards it should not be used anymore.
34  virtual void stop() = 0;
35 
36  virtual void logAttribute(const String &name, CPS::AttributeBase::Ptr attr, UInt rowsMax = 0, UInt colsMax = 0) {
37  if (auto attrReal = std::dynamic_pointer_cast<CPS::Attribute<Real>>(attr.getPtr())) {
38  mAttributes[name] = attrReal;
39  } else if (auto attrComp = std::dynamic_pointer_cast<CPS::Attribute<Complex>>(attr.getPtr())) {
40  mAttributes[name + ".re"] = attrComp->deriveReal();
41  mAttributes[name + ".im"] = attrComp->deriveImag();
42  } else if (auto attrInt = std::dynamic_pointer_cast<CPS::Attribute<Int>>(attr.getPtr())) {
43  mAttributes[name] = attrInt;
44  } else if (auto attrMatrix = std::dynamic_pointer_cast<CPS::Attribute<Matrix>>(attr.getPtr())) {
45  UInt rows = static_cast<UInt>((**attrMatrix).rows());
46  UInt cols = static_cast<UInt>((**attrMatrix).cols());
47  if (rowsMax == 0 || rowsMax > rows)
48  rowsMax = rows;
49  if (colsMax == 0 || colsMax > cols)
50  colsMax = cols;
51  if (rows == 1 && cols == 1) {
52  mAttributes[name] = attrMatrix->deriveCoeff<Real>(0, 0);
53  } else if (cols == 1) {
54  for (UInt k = 0; k < rowsMax; ++k) {
55  mAttributes[name + "_" + std::to_string(k)] = attrMatrix->deriveCoeff<Real>(k, 0);
56  }
57  } else {
58  for (UInt k = 0; k < rowsMax; ++k) {
59  for (UInt l = 0; l < colsMax; ++l) {
60  mAttributes[name + "_" + std::to_string(k) + "_" + std::to_string(l)] = attrMatrix->deriveCoeff<Real>(k, l);
61  }
62  }
63  }
64  } else if (auto attrMatrix = std::dynamic_pointer_cast<CPS::Attribute<MatrixComp>>(attr.getPtr())) {
65  UInt rows = static_cast<UInt>((**attrMatrix).rows());
66  UInt cols = static_cast<UInt>((**attrMatrix).cols());
67  if (rowsMax == 0 || rowsMax > rows)
68  rowsMax = rows;
69  if (colsMax == 0 || colsMax > cols)
70  colsMax = cols;
71  if (rows == 1 && cols == 1) {
72  mAttributes[name + ".re"] = attrMatrix->deriveCoeff<Complex>(0, 0)->deriveReal();
73  mAttributes[name + ".im"] = attrMatrix->deriveCoeff<Complex>(0, 0)->deriveImag();
74  } else if (cols == 1) {
75  for (UInt k = 0; k < rowsMax; ++k) {
76  mAttributes[name + "_" + std::to_string(k) + ".re"] = attrMatrix->deriveCoeff<Complex>(k, 0)->deriveReal();
77  mAttributes[name + "_" + std::to_string(k) + ".im"] = attrMatrix->deriveCoeff<Complex>(k, 0)->deriveImag();
78  }
79  } else {
80  for (UInt k = 0; k < rowsMax; ++k) {
81  for (UInt l = 0; l < colsMax; ++l) {
82  mAttributes[name + "_" + std::to_string(k) + "_" + std::to_string(l) + ".re"] = attrMatrix->deriveCoeff<Complex>(k, l)->deriveReal();
83  mAttributes[name + "_" + std::to_string(k) + "_" + std::to_string(l) + ".im"] = attrMatrix->deriveCoeff<Complex>(k, l)->deriveImag();
84  }
85  }
86  }
87  } else {
88  throw std::runtime_error("DataLoggerInterface: Unknown attribute type for attribute " + name);
89  }
90  }
91 
94  void logAttribute(const std::vector<String> &name, CPS::AttributeBase::Ptr attr) {
95  if (auto attrMatrix = std::dynamic_pointer_cast<CPS::Attribute<Matrix>>(attr.getPtr())) {
96  if ((**attrMatrix).rows() == 1 && (**attrMatrix).cols() == 1) {
97  logAttribute(name[0], attrMatrix->deriveCoeff<CPS::Real>(0, 0));
98  } else if ((**attrMatrix).cols() == 1) {
99  for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
100  logAttribute(name[k], attrMatrix->deriveCoeff<CPS::Real>(k, 0));
101  }
102  } else {
103  for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
104  for (UInt l = 0; l < (**attrMatrix).cols(); ++l) {
105  logAttribute(name[k * (**attrMatrix).cols() + l], attrMatrix->deriveCoeff<CPS::Real>(k, l));
106  }
107  }
108  }
109  } else if (auto attrMatrix = std::dynamic_pointer_cast<CPS::Attribute<MatrixComp>>(attr.getPtr())) {
110  if ((**attrMatrix).rows() == 1 && (**attrMatrix).cols() == 1) {
111  logAttribute(name[0], attrMatrix->deriveCoeff<CPS::Complex>(0, 0));
112  } else if ((**attrMatrix).cols() == 1) {
113  for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
114  logAttribute(name[k], attrMatrix->deriveCoeff<CPS::Complex>(k, 0));
115  }
116  } else {
117  for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
118  for (UInt l = 0; l < (**attrMatrix).cols(); ++l) {
119  logAttribute(name[k * (**attrMatrix).cols() + l], attrMatrix->deriveCoeff<CPS::Complex>(k, l));
120  }
121  }
122  }
123  }
124  }
125 
126  virtual void log(Real time, Int timeStepCount) = 0;
127 
128  virtual CPS::Task::Ptr getTask() = 0;
129 };
130 } // namespace DPsim
void logAttribute(const std::vector< String > &name, CPS::AttributeBase::Ptr attr)