Commit 8907783d authored by Georg Martin Reinke's avatar Georg Martin Reinke
Browse files

add interface for exporting currents to VILLASnode

parent 9667f481
......@@ -57,6 +57,9 @@ namespace DPsim {
/// Upgrade variable values based on the solution of the step
virtual void postStep(SystemModel& system) { }
/// Return the current flowing through this component in the previous timestep
virtual Complex getCurrent(SystemModel& system) { }
};
}
......
......@@ -14,3 +14,7 @@ void ExternalInterface::registerCurrentSource(ExternalCurrentSource *ecs, Int re
void ExternalInterface::registerExportedVoltage(Int from, Int to, Int realIdx, Int imagIdx) {
mExportedVoltages.push_back({from, to, realIdx, imagIdx});
}
void ExternalInterface::registerExportedCurrent(BaseComponent *comp, Int realIdx, Int imagIdx) {
mExportedCurrents.push_back({comp, realIdx, imagIdx});
}
......@@ -12,12 +12,12 @@ namespace DPsim {
Int realIdx;
Int imagIdx;
};
struct ExtComponent {
BaseComponent *comp;
Int realIdx;
Int imagIdx;
};
/** Abstract base class for interfacing the simulator with other data sources or sinks.
* After an ExternalInterface is created, components that should use values
* from this interface can be registered with it using the appropiate
......@@ -29,10 +29,12 @@ namespace DPsim {
protected:
std::vector<ExtComponent> mExtComponents;
std::vector<VoltDiff> mExportedVoltages;
std::vector<ExtComponent> mExportedCurrents;
public:
void registerVoltageSource(ExternalVoltageSource* evs, Int realIdx, Int imagIdx);
void registerCurrentSource(ExternalCurrentSource* ecs, Int realIdx, Int imagIdx);
void registerExportedVoltage(Int from, Int to, Int realIdx, Int imagIdx);
void registerExportedCurrent(BaseComponent *comp, Int realIdx, Int imagIdx);
virtual void readValues() = 0;
virtual void writeValues(SystemModel &model) = 0;
virtual ~ExternalInterface() {};
......
......@@ -11,13 +11,12 @@ void SystemModel::initialize(Int numNodes, Int numIdealVS) {
mRightSideVector = Matrix::Zero(mNumNodes, 1);
mLeftSideVector = DPSMatrix::Zero(mNumNodes, 1);
mSystemMatrix = DPSMatrix::Zero(mNumNodes, mNumNodes);
}
else {
mRightSideVector = DPSMatrix::Zero(2 * mNumNodes, 1);
mLeftSideVector = DPSMatrix::Zero(2 * mNumNodes, 1);
mSystemMatrix = DPSMatrix::Zero(2 * mNumNodes, 2 * mNumNodes);
mCurrentMatrix.resize(mNumNodes, mNumNodes);
}
switchSystemMatrix(0);
......@@ -68,3 +67,35 @@ void SystemModel::switchSystemMatrix(Int systemMatrixIndex) {
void SystemModel::setRightSideVectorToZero() {
mRightSideVector.setZero();
}
void SystemModel::resetCurrents() {
mCurrentMatrix.setZero();
}
void SystemModel::addCurrent(Int node1, Int node2, Complex value) {
if (node1 >= 0) {
if (node2 >= 0) {
mCurrentMatrix.coeffRef(node1, node2) += value;
mCurrentMatrix.coeffRef(node2, node1) -= value;
} else {
mCurrentMatrix.coeffRef(node1, node1) += value;
}
} else if (node2 >= 0) {
mCurrentMatrix.coeffRef(node2, node2) -= value;
}
}
Complex SystemModel::getCurrent(Int node1, Int node2) {
if (node1 >= 0) {
if (node2 >= 0) {
return mCurrentMatrix.coeffRef(node1, node2);
}
return mCurrentMatrix.coeffRef(node1, node1);
}
else if (node2 >= 0) {
return -mCurrentMatrix.coeffRef(node2, node2);
}
// shouldn't happen, but return a sensible value anyway
return Complex(0, 0);
}
......@@ -40,6 +40,9 @@ namespace DPsim {
/// Vector of unknown quantities
DPSMatrix mLeftSideVector;
/** Matrix of all edge currents; diagonal is used for currents to ground. */
SparseMatrixComp mCurrentMatrix;
public:
SystemModel() { }
void initialize(Int numNodes, Int numIdealVS);
......@@ -72,6 +75,10 @@ namespace DPsim {
void addRealToRightSideVector(Int row, Real value);
void setRightSideVectorToZero();
void resetCurrents();
void addCurrent(Int node1, Int node2, Complex value);
Complex getCurrent(Int node1, Int node2);
void solve();
};
}
......
......@@ -74,6 +74,19 @@ void VillasInterface::writeValues(SystemModel& model) {
if (vd.imagIdx > len)
len = vd.imagIdx;
}
for (auto cd : mExportedCurrents) {
Complex current = cd.comp->getCurrent(model);
if (cd.realIdx >= sample->capacity || cd.imagIdx >= sample->capacity) {
std::cerr << "fatal error: not enough space in allocated struct sample" << std::endl;
std::exit(1);
}
sample->data[cd.realIdx].f = current.real();
sample->data[cd.imagIdx].f = current.imag();
if (cd.realIdx > len)
len = cd.realIdx;
if (cd.imagIdx > len)
len = cd.imagIdx;
}
sample->length = len+1;
sample->sequence = mSeq++;
clock_gettime(CLOCK_REALTIME, &sample->ts.origin);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment