Commit 28b857a6 authored by Jan Dinkelbach's avatar Jan Dinkelbach Committed by Markus Mirz
Browse files

refactor task definition of piline in sp1ph and add validation to piline notebook

parent 0ea5575e
......@@ -20,7 +20,7 @@ set(CIRCUIT_SOURCES
# DP examples with PF initialization
Circuits/DP_Slack_PiLine_PQLoad_with_PF_Init.cpp
Circuits/DP_Slack_PiLine_VSI_with_PF_Init.cpp
# Powerflow examples
Circuits/PF_Slack_PiLine_PQLoad.cpp
......@@ -40,6 +40,7 @@ set(CIRCUIT_SOURCES
# SP examples
Circuits/SP_Circuits.cpp
Circuits/SP_PiLine.cpp
# Combined EMT/DP/SP examples
Circuits/EMT_DP_SP_Slack.cpp
......
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
* EONERC, RWTH Aachen University
* DPsim
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <DPsim.h>
using namespace DPsim;
using namespace CPS::SP;
void simElements() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "SP_PiLine_Elements";
Logger::setLogDir("logs/"+simName);
// Nodes
auto n1 = SimNode::make("n1");
auto n2 = SimNode::make("n2");
auto vn1 = SimNode::make("vn1");
// Components
auto vs = Ph1::VoltageSource::make("v_1");
vs->setParameters(CPS::Math::polar(100000, 0));
// Parametrization of components
Real resistance = 5;
Real inductance = 0.16;
Real capacitance = 1.0e-6;
Real conductance = 1e-6;
auto res = Ph1::Resistor::make("R_line");
res->setParameters(resistance);
auto ind = Ph1::Inductor::make("L_line");
ind->setParameters(inductance);
auto cap1 = Ph1::Capacitor::make("Cp_1");
cap1->setParameters(capacitance/2.);
auto cap2 = Ph1::Capacitor::make("Cp_2");
cap2->setParameters(capacitance/2.);
auto con1 = Ph1::Resistor::make("Gp_1");
con1->setParameters(2./conductance);
auto con2 = Ph1::Resistor::make("Gp_2");
con2->setParameters(2./conductance);
auto load = Ph1::Resistor::make("R_load");
load->setParameters(10000);
// Topology
vs->connect({ SimNode::GND, n1 });
res->connect({n1, vn1});
ind->connect({vn1, n2});
cap1->connect({n1, SimNode::GND});
cap2->connect({n2, SimNode::GND});
con1->connect({n1, SimNode::GND});
con2->connect({n2, SimNode::GND});
load->connect({ n2, SimNode::GND });
auto sys = SystemTopology(50,
SystemNodeList{n1, n2, vn1},
SystemComponentList{vs, res, ind, cap1, cap2, con1, con2, load});
//SystemComponentList{vs, res, ind, cap1, cap2, load});
//SystemComponentList{vs, res, ind, load});
// SystemComponentList{vs, ind, load});
// SystemComponentList{vs, res, load});
// Logging
auto logger = DataLogger::make(simName);
logger->addAttribute("v1", n1->attribute("v"));
logger->addAttribute("v2", n2->attribute("v"));
logger->addAttribute("iline", ind->attribute("i_intf"));
logger->addAttribute("iload", load->attribute("i_intf"));
Simulation sim(simName);
sim.setSystem(sys);
sim.setTimeStep(timeStep);
sim.setFinalTime(finalTime);
sim.setDomain(Domain::SP);
sim.addLogger(logger);
sim.run();
}
void simPiLine() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "SP_PiLine_Component";
Logger::setLogDir("logs/"+simName);
// Nodes
auto n1 = SimNode::make("n1");
auto n2 = SimNode::make("n2");
// Components
auto vs = Ph1::VoltageSource::make("v_1", Logger::Level::debug);
vs->setParameters(CPS::Math::polar(100000, 0));
// Parametrization of components
Real resistance = 5;
Real inductance = 0.16;
Real capacitance = 1.0e-6;
Real conductance = 1e-6;
auto line = Ph1::PiLine::make("Line", Logger::Level::debug);
line->setParameters(resistance, inductance, capacitance, conductance);
auto load = Ph1::Resistor::make("R_load", Logger::Level::debug);
load->setParameters(10000);
// Topology
vs->connect({ SimNode::GND, n1 });
line->connect({ n1, n2 });
load->connect({ n2, SimNode::GND });
auto sys = SystemTopology(50,
SystemNodeList{n1, n2},
SystemComponentList{vs, line, load});
// Logging
auto logger = DataLogger::make(simName);
logger->addAttribute("v1", n1->attribute("v"));
logger->addAttribute("v2", n2->attribute("v"));
logger->addAttribute("iline", line->attribute("i_intf"));
logger->addAttribute("iload", load->attribute("i_intf"));
Simulation sim(simName);
sim.setSystem(sys);
sim.setTimeStep(timeStep);
sim.setFinalTime(finalTime);
sim.addLogger(logger);
sim.setDomain(Domain::SP);
sim.run();
}
int main(int argc, char* argv[]) {
simElements();
simPiLine();
}
......@@ -9,10 +9,111 @@
from villas.dataprocessing.timeseries import TimeSeries as ts
import matplotlib.pyplot as plt
import numpy as np
#%matplotlib widget
epsilon = 1e-12
```
%% Cell type:markdown id: tags:
## SP PiLine with RLC elements
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${TOP}/build/Examples/Cxx
SP_PiLine
```
%% Cell type:code id: tags:
``` python
work_dir = 'logs/SP_PiLine_Elements/'
log_name = 'SP_PiLine_Elements'
print(work_dir + log_name + '.csv')
piline_elements = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
piline_elements_sp_shifted = ts.frequency_shift_list(piline_elements, 50)
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(piline_elements_sp_shifted['v1_shift'].time, piline_elements_sp_shifted['v1_shift'].values, label='v1_shift')
plt.plot(piline_elements_sp_shifted['v2_shift'].time, piline_elements_sp_shifted['v2_shift'].values, label='v2_shift', linestyle=':')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(piline_elements_sp_shifted['iline_shift'].time, piline_elements_sp_shifted['iline_shift'].values, label='iline_shift')
plt.legend()
```
%% Cell type:markdown id: tags:
## SP PiLine composite model
%% Cell type:code id: tags:
``` python
work_dir = 'logs/SP_PiLine_Component/'
log_name = 'SP_PiLine_Component'
print(work_dir + log_name + '.csv')
piline_component = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
piline_component_sp_shifted = ts.frequency_shift_list(piline_component, 50)
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(piline_component_sp_shifted['v1_shift'].time, piline_component_sp_shifted['v1_shift'].values, label='v1_shift')
plt.plot(piline_component_sp_shifted['v2_shift'].time, piline_component_sp_shifted['v2_shift'].values, label='v2_shift', linestyle=':')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(piline_component_sp_shifted['iline_shift'].time, piline_component_sp_shifted['iline_shift'].values, label='iline_shift')
plt.legend()
```
%% Cell type:markdown id: tags:
## Error for SP PiLine
%% Cell type:code id: tags:
``` python
plt.figure()
for name in ['v1_shift', 'v2_shift', 'iline_shift']:
plt.plot(piline_elements_sp_shifted[name].time, piline_elements_sp_shifted[name].values - piline_component_sp_shifted[name].values, label=name+'_error')
plt.legend()
```
%% Cell type:markdown id: tags:
## Assertion for SP PiLine
%% Cell type:code id: tags:
``` python
errors_sp_shifted = []
for name in ['v1_shift', 'v2_shift', 'iline_shift']:
errors_sp_shifted.append(np.absolute(piline_elements_sp_shifted[name].values - piline_component_sp_shifted[name].values).max())
print(name + ': ' + str(errors_sp_shifted[-1]))
assert np.max(errors_sp_shifted) < epsilon
```
%% Cell type:markdown id: tags:
## DP PiLine with RLC elements
......@@ -42,11 +143,10 @@
``` python
plt.figure()
plt.plot(piline_elements_dp_shifted['v1_shift'].time, piline_elements_dp_shifted['v1_shift'].values, label='v1_shift')
plt.plot(piline_elements_dp_shifted['v2_shift'].time, piline_elements_dp_shifted['v2_shift'].values, label='v2_shift', linestyle=':')
plt.legend()
#plt.xlim([0,0.02])
```
%% Cell type:code id: tags:
``` python
......@@ -74,11 +174,10 @@
``` python
plt.figure()
plt.plot(piline_component_dp_shifted['v1_shift'].time, piline_component_dp_shifted['v1_shift'].values, label='v1_shift')
plt.plot(piline_component_dp_shifted['v2_shift'].time, piline_component_dp_shifted['v2_shift'].values, label='v2_shift', linestyle=':')
plt.legend()
#plt.xlim([0,0.02])
```
%% Cell type:code id: tags:
``` python
......@@ -109,11 +208,11 @@
``` python
errors_dp_shifted = []
for name in ['v1_shift', 'v2_shift', 'iline_shift']:
errors_dp_shifted.append(np.absolute(piline_elements_dp_shifted[name].values - piline_component_dp_shifted[name].values).max())
print(name + ': ' + str(errors_dp_shifted[-1]))
assert np.max(errors_dp_shifted) < 1e-3
assert np.max(errors_dp_shifted) < epsilon
```
%% Cell type:markdown id: tags:
## EMT PiLine with RLC elements
......@@ -142,11 +241,10 @@
``` python
plt.figure()
plt.plot(piline_elements_emt['v1_0'].time, piline_elements_emt['v1_0'].values, label='v1_0')
plt.plot(piline_elements_emt['v2_0'].time, piline_elements_emt['v2_0'].values, label='v2_0', linestyle=':')
plt.legend()
#plt.xlim([0,0.02])
```
%% Cell type:code id: tags:
``` python
......@@ -173,11 +271,10 @@
``` python
plt.figure()
plt.plot(piline_component_emt['v1_0'].time, piline_component_emt['v1_0'].values, label='v1_0')
plt.plot(piline_component_emt['v2_0'].time, piline_component_emt['v2_0'].values, label='v2_0', linestyle=':')
plt.legend()
#plt.xlim([0,0.02])
```
%% Cell type:code id: tags:
``` python
......@@ -186,11 +283,11 @@
plt.legend()
```
%% Cell type:markdown id: tags:
## Error for DP PiLine
## Error for EMT PiLine
%% Cell type:code id: tags:
``` python
plt.figure()
......@@ -208,11 +305,11 @@
``` python
errors_emt = []
for name in ['v1_0', 'v2_0', 'iline_0']:
errors_emt.append(np.absolute(piline_elements_emt[name].values - piline_component_emt[name].values).max())
print(name + ': ' + str(errors_emt[-1]))
assert np.max(errors_emt) < 1e-3
assert np.max(errors_emt) < epsilon
```
%% Cell type:markdown id: tags:
## Compare PiLine Component DP vs. EMT
......
......@@ -19,6 +19,10 @@
namespace CPS {
namespace SP {
namespace Ph1 {
/// \brief PI-line static phasor model
///
/// For MNA this model consists sub components to represent the
/// RLC elements of a PI-line.
class PiLine :
public SimPowerComp<Complex>,
public MNATearInterface,
......@@ -26,9 +30,6 @@ namespace Ph1 {
public Base::Ph1::PiLine,
public PFSolverInterfaceBranch {
protected:
/// Nominal omega
Real mNominalOmega;
///base voltage [V]
Real mBaseVoltage;
///base current [A]
......@@ -82,9 +83,9 @@ namespace Ph1 {
std::shared_ptr<Capacitor> mSubParallelCapacitor0;
/// Parallel resistor submodel at Terminal 1
std::shared_ptr<Resistor> mSubParallelResistor1;
// Parallel capacitor submodel at Terminal 1
/// Parallel capacitor submodel at Terminal 1
std::shared_ptr<Capacitor> mSubParallelCapacitor1;
///
/// Right side vectors of subcomponents
std::vector<const Matrix*> mRightVectorStamps;
public:
// #### General ####
......@@ -96,7 +97,7 @@ namespace Ph1 {
///
SimPowerComp<Complex>::Ptr clone(String copySuffix) override;
///
void setParameters(Real resistance, Real inductance, Real capacitance = -1, Real conductance = -1, Real omega = -1);
void setParameters(Real resistance, Real inductance, Real capacitance = -1, Real conductance = -1);
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency) override;
......@@ -121,23 +122,24 @@ namespace Ph1 {
void mnaInitialize(Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) override;
/// Stamps system matrix
void mnaApplySystemMatrixStamp(Matrix& systemMatrix) override;
/// Stamps right side (source) vector
void mnaApplyRightSideVectorStamp(Matrix& rightVector);
/// Updates internal current variable of the component
void mnaUpdateCurrent(const Matrix& leftVector) override;
/// Updates internal voltage variable of the component
void mnaUpdateVoltage(const Matrix& leftVector) override;
/// MNA post-step operations
void mnaPostStep(Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector);
/// add MNA post-step dependencies
void mnaAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute<Matrix>::Ptr &leftVector);
class MnaPostStep : public Task {
public:
MnaPostStep(PiLine& line, Attribute<Matrix>::Ptr leftVector) :
Task(line.mName + ".MnaPostStep"), mLine(line), mLeftVector(leftVector) {
mAttributeDependencies.push_back(leftVector);
mAttributeDependencies.push_back(line.mSubSeriesInductor->attribute("i_intf"));
mModifiedAttributes.push_back(line.attribute("i_intf"));
mModifiedAttributes.push_back(line.attribute("v_intf"));
mLine.mnaAddPostStepDependencies(mPrevStepDependencies, mAttributeDependencies, mModifiedAttributes, mLeftVector);
}
void execute(Real time, Int timeStepCount);
void execute(Real time, Int timeStepCount) { mLine.mnaPostStep(time, timeStepCount, mLeftVector); };
private:
PiLine& mLine;
Attribute<Matrix>::Ptr mLeftVector;
......
......@@ -383,7 +383,7 @@ TopologicalPowerComp::Ptr Reader::mapACLineSegment(CIMPP::ACLineSegment* line) {
}
else if (mDomain == Domain::SP) {
auto cpsLine = std::make_shared<SP::Ph1::PiLine>(line->mRID, line->name, mComponentLogLevel);
cpsLine->setParameters(resistance, inductance, capacitance, conductance, mOmega);
cpsLine->setParameters(resistance, inductance, capacitance, conductance);
cpsLine->setBaseVoltage(baseVoltage);
return cpsLine;
}
......
......@@ -37,11 +37,11 @@ SP::Ph1::PiLine::PiLine(String uid, String name, Logger::Level logLevel)
addAttribute<Real>("q_inj", &mReactivePowerInjection, Flags::read | Flags::write);
}
void SP::Ph1::PiLine::setParameters(Real resistance, Real inductance, Real capacitance, Real conductance, Real omega) {
mNominalOmega = omega;
void SP::Ph1::PiLine::setParameters(Real resistance, Real inductance, Real capacitance, Real conductance) {
mSeriesRes = resistance;
mSeriesInd = inductance;
mSLog->info("Resistance={} [Ohm] Inductance={} [H]", mSeriesRes, mNominalOmega*mSeriesInd);
mSLog->info("Resistance={} [Ohm] Inductance={} [H]", mSeriesRes, mSeriesInd);
if(capacitance > 0){
mParallelCap = capacitance;
......@@ -58,7 +58,7 @@ void SP::Ph1::PiLine::setParameters(Real resistance, Real inductance, Real capac
mParallelCond = (conductance > 0) ? conductance : 1e-6;
mSLog->warn("Zero value for Conductance, setting default value of G={} [S]", mParallelCond);
}
mSLog->info("Suceptance={} [S] Conductance={} [S]", mNominalOmega*mParallelCap, mParallelCond);
mSLog->info("Capacitance={} [F] Conductance={} [S]", mParallelCap, mParallelCond);
mSLog->flush();
mParametersSet = true;
......@@ -66,7 +66,7 @@ void SP::Ph1::PiLine::setParameters(Real resistance, Real inductance, Real capac
SimPowerComp<Complex>::Ptr SP::Ph1::PiLine::clone(String name) {
auto copy = PiLine::make(name, mLogLevel);
copy->setParameters(mBaseVoltage, mSeriesRes, mSeriesInd, mParallelCap, mParallelCond);
copy->setParameters(mSeriesRes, mSeriesInd, mParallelCap, mParallelCond);
return copy;
}
......@@ -167,38 +167,44 @@ void SP::Ph1::PiLine::initializeFromNodesAndTerminals(Real frequency) {
mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(0) + mIntfCurrent(0, 0) * mSeriesRes);
// Create series sub components
mSubSeriesResistor = std::make_shared<SP::Ph1::Resistor>(mName + "_res", Logger::Level::off);
mSubSeriesResistor = std::make_shared<SP::Ph1::Resistor>(mName + "_res", Logger::Level::info);
mSubSeriesResistor->setParameters(mSeriesRes);
mSubSeriesResistor->connect({ mTerminals[0]->node(), mVirtualNodes[0] });
mSubSeriesResistor->initialize(mFrequencies);
mSubSeriesResistor->initializeFromNodesAndTerminals(frequency);
mSubSeriesInductor = std::make_shared<SP::Ph1::Inductor>(mName + "_ind", Logger::Level::off);
mSubSeriesInductor = std::make_shared<SP::Ph1::Inductor>(mName + "_ind", Logger::Level::info);
mSubSeriesInductor->setParameters(mSeriesInd);
mSubSeriesInductor->connect({ mVirtualNodes[0], mTerminals[1]->node() });
mSubSeriesInductor->initialize(mFrequencies);
mSubSeriesInductor->initializeFromNodesAndTerminals(frequency);
// Create parallel sub components
if (mParallelCond >= 0) {
mSubParallelResistor0 = std::make_shared<SP::Ph1::Resistor>(mName + "_con0", Logger::Level::off);
mSubParallelResistor0 = std::make_shared<SP::Ph1::Resistor>(mName + "_con0", Logger::Level::info);
mSubParallelResistor0->setParameters(2. / mParallelCond);
mSubParallelResistor0->connect(SimNode::List{ SimNode::GND, mTerminals[0]->node() });
mSubParallelResistor0->initialize(mFrequencies);
mSubParallelResistor0->initializeFromNodesAndTerminals(frequency);
mSubParallelResistor1 = std::make_shared<SP::Ph1::Resistor>(mName + "_con1", Logger::Level::off);
mSubParallelResistor1 = std::make_shared<SP::Ph1::Resistor>(mName + "_con1", Logger::Level::info);
mSubParallelResistor1->setParameters(2. / mParallelCond);
mSubParallelResistor1->connect(SimNode::List{ SimNode::GND, mTerminals[1]->node() });
mSubParallelResistor1->initialize(mFrequencies);
mSubParallelResistor1->initializeFromNodesAndTerminals(frequency);
}
if (mParallelCap >= 0) {
mSubParallelCapacitor0 = std::make_shared<SP::Ph1::Capacitor>(mName + "_cap0", Logger::Level::off);
mSubParallelCapacitor0 = std::make_shared<SP::Ph1::Capacitor>(mName + "_cap0", Logger::Level::info);
mSubParallelCapacitor0->setParameters(mParallelCap / 2.);
mSubParallelCapacitor0->connect(SimNode::List{ SimNode::GND, mTerminals[0]->node() });
mSubParallelCapacitor0->initialize(mFrequencies);
mSubParallelCapacitor0->initializeFromNodesAndTerminals(frequency);
mSubParallelCapacitor1 = std::make_shared<SP::Ph1::Capacitor>(mName + "_cap1", Logger::Level::off);
mSubParallelCapacitor1 = std::make_shared<SP::Ph1::Capacitor>(mName + "_cap1", Logger::Level::info);
mSubParallelCapacitor1->setParameters(mParallelCap / 2.);
mSubParallelCapacitor1->connect(SimNode::List{ SimNode::GND, mTerminals[1]->node() });
mSubParallelCapacitor1->initialize(mFrequencies);
mSubParallelCapacitor1->initializeFromNodesAndTerminals(frequency);
}
......@@ -224,23 +230,22 @@ void SP::Ph1::PiLine::mnaInitialize(Real omega, Real timeStep, Attribute<Matrix>
mSubSeriesResistor->mnaInitialize(omega, timeStep, leftVector);
mSubSeriesInductor->mnaInitialize(omega, timeStep, leftVector);
if (mParallelCond >= 0) {
mSubParallelResistor0->mnaInitialize(omega, timeStep, leftVector);
mSubParallelResistor1->mnaInitialize(omega, timeStep, leftVector);
subComps.push_back(mSubParallelResistor0);
subComps.push_back(mSubParallelResistor1);
}
mRightVectorStamps.push_back(&mSubSeriesInductor->attribute<Matrix>("right_vector")->get());
mSubParallelResistor0->mnaInitialize(omega, timeStep, leftVector);
mSubParallelResistor1->mnaInitialize(omega, timeStep, leftVector);
subComps.push_back(mSubParallelResistor0);
subComps.push_back(mSubParallelResistor1);
if (mParallelCap >= 0) {
mSubParallelCapacitor0->mnaInitialize(omega, timeStep, leftVector);
mSubParallelCapacitor1->mnaInitialize(omega, timeStep, leftVector);
mRightVectorStamps.push_back(&mSubParallelCapacitor0->attribute<Matrix>("right_vector")->get());
mRightVectorStamps.push_back(&mSubParallelCapacitor1->attribute<Matrix>("right_vector")->get());
subComps.push_back(mSubParallelCapacitor0);
subComps.push_back(mSubParallelCapacitor1);
}
for (auto comp : subComps) {
for (auto task : comp->mnaTasks()) {
mMnaTasks.push_back(task);
}
}
mMnaTasks.push_back(std::make_shared<MnaPostStep>(*this, leftVector));
mRightVector = Matrix::Zero(leftVector->get().rows(), 1);
}
......@@ -248,19 +253,55 @@ void SP::Ph1::PiLine::mnaInitialize(Real omega, Real timeStep, Attribute<Matrix>
void SP::Ph1::PiLine::mnaApplySystemMatrixStamp(Matrix& systemMatrix) {
mSubSeriesResistor->mnaApplySystemMatrixStamp(systemMatrix);
mSubSeriesInductor->mnaApplySystemMatrixStamp(systemMatrix);
if (mParallelCond >= 0) {
mSubParallelResistor0->mnaApplySystemMatrixStamp(systemMatrix);
mSubParallelResistor1->mnaApplySystemMatrixStamp(systemMatrix);
}
mSubParallelResistor0->mnaApplySystemMatrixStamp(systemMatrix);
mSubParallelResistor1->mnaApplySystemMatrixStamp(systemMatrix);
if (mParallelCap >= 0) {
mSubParallelCapacitor0->mnaApplySystemMatrixStamp(systemMatrix);
mSubParallelCapacitor1->mnaApplySystemMatrixStamp(systemMatrix);
}
}
void SP::Ph1::PiLine::MnaPostStep::execute(Real time, Int timeStepCount) {
mLine.mnaUpdateVoltage(*mLeftVector);
mLine.mnaUpdateCurrent(*mLeftVector);
void SP::Ph1::PiLine::mnaApplyRightSideVectorStamp(Matrix& rightVector) {
rightVector.setZero();
for (auto stamp : mRightVectorStamps)
rightVector += *stamp;
}
void SP::Ph1::PiLine::mnaAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute<Matrix>::Ptr &leftVector) {
// add post-step dependencies of subcomponents
this->mSubSeriesResistor->mnaAddPostStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes, leftVector);
this->mSubSeriesInductor->mnaAddPostStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes, leftVector);
if (this->mParallelCap >= 0) {
this->mSubParallelCapacitor0->mnaAddPostStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes, leftVector);
this->mSubParallelCapacitor1->mnaAddPostStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes, leftVector);
}