Commit a84e2861 authored by Steffen Vogel's avatar Steffen Vogel 🎅🏼
Browse files

Merge branch 'refactoring' into 'development'

Refactoring

See merge request acs/core/simulation/dpsim!38
parents 3990d78e ff143f8b
......@@ -177,7 +177,4 @@
<cim:SvTapStep.position>-68</cim:SvTapStep.position>
<cim:SvTapStep.TapChanger rdf:resource="#_DA12-2E-F1-031303736393233313038"/>
</cim:SvTapStep>
<cim:TopologicalIsland rdf:ID="Bus 01-SLACK">
<cim:TopologicalIsland.AngleRef_TopologicalNode rdf:resource="#Bus 01"/>
</cim:TopologicalIsland>
</rdf:RDF>
......@@ -459,7 +459,4 @@
<cim:SvTapStep.position>6</cim:SvTapStep.position>
<cim:SvTapStep.TapChanger rdf:resource="#_DA12-2E-F1-00000000383231363934"/>
</cim:SvTapStep>
<cim:TopologicalIsland rdf:ID="N31-SLACK">
<cim:TopologicalIsland.AngleRef_TopologicalNode rdf:resource="#N31"/>
</cim:TopologicalIsland>
</rdf:RDF>
......@@ -79,7 +79,4 @@
<cim:SvShuntCompensatorSections.sections>1</cim:SvShuntCompensatorSections.sections>
<cim:SvShuntCompensatorSections.ShuntCompensator rdf:resource="#SVC"/>
</cim:SvShuntCompensatorSections>
<cim:TopologicalIsland rdf:ID="BUS1-SLACK">
<cim:TopologicalIsland.AngleRef_TopologicalNode rdf:resource="#BUS1"/>
</cim:TopologicalIsland>
</rdf:RDF>
......@@ -13,6 +13,7 @@ IEEE-14_Neplan:
- Examples/CIM/IEEE-14_Neplan/Rootnet_FULL_NE_29J09h_EQ.xml
- Examples/CIM/IEEE-14_Neplan/Rootnet_FULL_NE_29J09h_SV.xml
- Examples/CIM/IEEE-14_Neplan/Rootnet_FULL_NE_29J09h_TP.xml
xfail: True
IEEE-39_Neplan:
cmd: build/Examples/Cxx/CIM
......@@ -20,4 +21,5 @@ IEEE-39_Neplan:
- Examples/CIM/IEEE-39_Neplan/Rootnet_FULL_NE_29J10h_DI.xml
- Examples/CIM/IEEE-39_Neplan/Rootnet_FULL_NE_29J10h_EQ.xml
- Examples/CIM/IEEE-39_Neplan/Rootnet_FULL_NE_29J10h_SV.xml
- Examples/CIM/IEEE-39_Neplan/Rootnet_FULL_NE_29J10h_TP.xml
\ No newline at end of file
- Examples/CIM/IEEE-39_Neplan/Rootnet_FULL_NE_29J10h_TP.xml
xfail: True
\ No newline at end of file
......@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
};
shmem.registerControllableSource(ecs, GND, 0);
shmem.registerExportedVoltage(0, GND, 0, 1);
shmem.registerExportedVoltage(ecs, 0, 1);
}
else {
std::cerr << "invalid test number" << std::endl;
......
......@@ -73,7 +73,8 @@ int main(int argc, char *argv[])
};
shmem.registerControllableSource(ecs, GND, 0);
shmem.registerExportedVoltage(0, GND, 0, 1);
// TODO: check if this was refactored correctly
shmem.registerExportedVoltage(ecs, 0, 1);
}
else {
std::cerr << "invalid test number" << std::endl;
......
......@@ -86,7 +86,10 @@ int main(int argc, char* argv[])
// Declare circuit components
Component::Ptr gen = SynchronGeneratorVBR::make("gen", 0, 1, 2,
nomPower, nomPhPhVoltRMS, nomFreq, poleNum, nomFieldCurr,
Rs, Ll, Lmd, Lmd0, Lmq, Lmq0, Rfd, Llfd, Rkd, Llkd, Rkq1, Llkq1, Rkq2, Llkq2, H);
Rs, Ll, Lmd, Lmd0, Lmq, Lmq0,
Rfd, Llfd, Rkd, Llkd,
Rkq1, Llkq1, Rkq2, Llkq2, H);
Real loadRes = 1037.8378;
Component::Ptr r1 = Resistor::make("r1", 0, GND, loadRes);
Component::Ptr r2 = Resistor::make("r2", 1, GND, loadRes);
......
......@@ -31,7 +31,7 @@ static void VarFreqRxLineResLoad_DP(Real timeStep, Real finalTime, Real freqStep
String simName = "DP_RXLine_LoadStep_FreqStep_1_" + std::to_string(timeStep);
Component::List comps0 = {
DP::VoltageSourceFreq::make("v_s", 0, GND, 1000, 0, 1, 2 * PI*-5, freqStep, rampTime),
std::make_shared<DP::VoltageSourceFreq>("v_s", 0, GND, 1000, 0, 1, 2 * PI*-5, freqStep, rampTime),
DP::Resistor::make("r_line", 0, 1, 1),
DP::Inductor::make("l_line", 1, 2, 0.2)
};
......@@ -55,7 +55,7 @@ static void VarFreqRxLineResLoad_EMT(Real timeStep, Real finalTime, Real freqSte
String simName = "EMT_RXLine_LoadStep_FreqStep_1_" + std::to_string(timeStep);
Component::List comps0 = {
DP::VoltageSourceFreq::make("v_s", 0, GND, 1000, 0, 1, 2 * PI*-5, freqStep, rampTime),
std::make_shared<EMT::VoltageSourceFreq>("v_s", 0, GND, 1000, 0, 1, 2 * PI*-5, freqStep, rampTime),
EMT::Resistor::make("r_line", 0, 1, 1),
EMT::Inductor::make("l_line", 1, 2, 0.2)
};
......
......@@ -32,7 +32,7 @@ static void VarFreqRxLineResLoad_NZ_Paper_DP(Real timeStep, Real finalTime, Real
String simName = "DP_RXLine_LoadStep_FreqStep_2_" + std::to_string(timeStep);
Component::List comps0 = {
DP::VoltageSourceFreq::make("v_s", 0, GND, 10000, 0, 1, 2 * PI*-1, freqStep, rampTime),
std::make_shared<DP::VoltageSourceFreq>("v_s", 0, GND, 10000, 0, 1, 2 * PI*-1, freqStep, rampTime),
DP::Resistor::make("r_line", 0, 1, 1),
DP::Inductor::make("l_line", 1, 2, 1)
};
......@@ -54,7 +54,7 @@ static void VarFreqRxLineResLoad_NZ_Paper_EMT(Real timeStep, Real finalTime, Rea
String simName = "EMT_RXLine_LoadStep_FreqStep_2_" + std::to_string(timeStep);
Component::List comps0 = {
EMT::VoltageSourceFreq::make("v_s", 0, GND, 10000, 0, 1, 2 * PI*-1, freqStep, rampTime),
std::make_shared<EMT::VoltageSourceFreq>("v_s", 0, GND, 10000, 0, 1, 2 * PI*-1, freqStep, rampTime),
EMT::Resistor::make("r_line", 0, 1, 1),
EMT::Inductor::make("l_line", 1, 2, 1)
};
......
......@@ -2,53 +2,48 @@ add_library(dpsim
SystemModel.cpp
Utilities.cpp
Simulation.cpp
MNA_Simulation.cpp
FaultSimulation.cpp
SynGenSimulation.cpp
CPowerSystems/Components/Attribute.cpp
CPowerSystems/IntegrationMethod.cpp
CPowerSystems/Logger.cpp
CPowerSystems/MathLibrary.cpp
CPowerSystems/Components/Component.cpp
CPowerSystems/IntegrationMethod.cpp
CPowerSystems/Logger.cpp
CPowerSystems/MathLibrary.cpp
SynGenSimulation.cpp
CPowerSystems/Source/Logger.cpp
CPowerSystems/Source/MathUtils.cpp
CPowerSystems/Source/Attribute.cpp
CPowerSystems/Source/Component.cpp
)
list(APPEND SOURCES
CPowerSystems/Components/Base_SynchronGenerator.cpp
CPowerSystems/Components/DP_Capacitor.cpp
CPowerSystems/Components/DP_CurrentSource.cpp
CPowerSystems/Components/DP_Inductor.cpp
CPowerSystems/Components/DP_Inductor_Interfaced.cpp
CPowerSystems/Components/DP_Line_Pi.cpp
CPowerSystems/Components/DP_Line_Rx.cpp
CPowerSystems/Components/DP_Load_PQ.cpp
CPowerSystems/Components/DP_Resistor.cpp
CPowerSystems/Components/DP_SynchronGenerator_Ideal.cpp
CPowerSystems/Components/DP_SynchronGenerator.cpp
CPowerSystems/Components/DP_SynchronGenerator_VBR.cpp
CPowerSystems/Components/DP_SynchronGenerator_VBR_Simplified.cpp
CPowerSystems/Components/DP_Transformer.cpp
CPowerSystems/Components/DP_Transformer_Ideal.cpp
CPowerSystems/Components/DP_VoltageSource.cpp
CPowerSystems/Components/DP_VoltageSource_Freq.cpp
CPowerSystems/Components/DP_VoltageSource_Norton.cpp
CPowerSystems/Components/EMT_Capacitor.cpp
CPowerSystems/Components/EMT_CurrentSource.cpp
CPowerSystems/Components/EMT_Inductor.cpp
CPowerSystems/Components/EMT_Resistor.cpp
CPowerSystems/Components/EMT_SynchronGenerator.cpp
CPowerSystems/Components/EMT_SynchronGenerator_Simplified.cpp
CPowerSystems/Components/EMT_SynchronGenerator_Simplified_CurrentSource.cpp
CPowerSystems/Components/EMT_SynchronGenerator_VBR.cpp
CPowerSystems/Components/EMT_VoltageSource.cpp
CPowerSystems/Components/EMT_VoltageSource_Freq.cpp
CPowerSystems/Components/EMT_VoltageSource_Norton.cpp
CPowerSystems/Components/Exciter.cpp
CPowerSystems/Components/TurbineGovernor.cpp
CPowerSystems/Components/EMT_SynchronGenerator_VBR_New.cpp
CPowerSystems/Components/DP_SynchronGenerator_VBR_New.cpp
CPowerSystems/Components/DP_SynchronGenerator_Simplified.cpp
list(APPEND SOURCES
CPowerSystems/Source/Components/DP_Capacitor.cpp
CPowerSystems/Source/Components/DP_CurrentSource.cpp
CPowerSystems/Source/Components/DP_Inductor.cpp
CPowerSystems/Source/Components/DP_Line_Pi.cpp
CPowerSystems/Source/Components/DP_Line_Rx.cpp
CPowerSystems/Source/Components/DP_Load_PQ.cpp
CPowerSystems/Source/Components/DP_Resistor.cpp
CPowerSystems/Source/Components/DP_Transformer.cpp
CPowerSystems/Source/Components/DP_VoltageSource.cpp
CPowerSystems/Source/Components/DP_VoltageSource_Freq.cpp
CPowerSystems/Source/Components/DP_VoltageSource_Norton.cpp
CPowerSystems/Source/Components/EMT_Capacitor.cpp
CPowerSystems/Source/Components/EMT_CurrentSource.cpp
CPowerSystems/Source/Components/EMT_Inductor.cpp
CPowerSystems/Source/Components/EMT_Resistor.cpp
CPowerSystems/Source/Components/EMT_VoltageSource.cpp
CPowerSystems/Source/Components/EMT_VoltageSource_Freq.cpp
CPowerSystems/Source/Components/EMT_VoltageSource_Norton.cpp
CPowerSystems/Source/Components/Exciter.cpp
CPowerSystems/Source/Components/TurbineGovernor.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_Ideal.cpp
CPowerSystems/Source/Components/Base_SynchronGenerator.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_Classic_Simplified.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_Classic.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_VBR.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_VBR_UnitTest.cpp
CPowerSystems/Source/Components/DP_SynchronGenerator_VBR_Simplified.cpp
CPowerSystems/Source/Components/EMT_SynchronGenerator_Classic.cpp
CPowerSystems/Source/Components/EMT_SynchronGenerator_Classic_Simplified.cpp
CPowerSystems/Source/Components/EMT_SynchronGenerator_Classic_Simpl_CurrentComp.cpp
CPowerSystems/Source/Components/EMT_SynchronGenerator_VBR.cpp
CPowerSystems/Source/Components/EMT_SynchronGenerator_VBR_UnitTest.cpp
)
set(INCLUDE_DIRS
......@@ -75,8 +70,8 @@ if(WITH_SHMEM)
list(APPEND INCLUDE_DIRS ${VILLASNODE_INCLUDE_DIRS})
list(APPEND SOURCES
CPowerSystems/ExternalInterface.cpp
CPowerSystems/ShmemInterface.cpp
CPowerSystems/Source/Interfaces/ExternalInterface.cpp
CPowerSystems/Source/Interfaces/ShmemInterface.cpp
)
endif()
......@@ -88,7 +83,7 @@ if(WITH_PYTHON)
endif()
if(WITH_CIM)
list(APPEND SOURCES CPowerSystems/CIM/Reader.cpp)
list(APPEND SOURCES CPowerSystems/Source/CIM/Reader.cpp)
list(APPEND INCLUDE_DIRS ${CIMPP_INCLUDE_DIRS})
list(APPEND LIBRARIES ${CIMPP_LIBRARIES})
endif()
......
Subproject commit ed0020d13cb7f8680ea81f4e117b189bbeef27f7
Subproject commit ac4ed85ec3bec5ff9dfd81ee5601bd70e329400a
#include "Simulation.h"
#include "CPowerSystems/Components.h"
#include "CPowerSystems/Logger.h"
#include "CPowerSystems/Source/Components.h"
#include "CPowerSystems/Source/Logger.h"
#include "RealTimeSimulation.h"
#include "CPowerSystems/ShmemInterface.h"
#ifdef WITH_SHMEM
#include "CPowerSystems/Source/Interfaces/ShmemInterface.h"
#endif
\ No newline at end of file
......@@ -94,7 +94,7 @@ Int FaultSimulation::step(bool blocking)
}
for (auto eif : mExternalInterfaces) {
eif->writeValues(mSystemModel);
eif->writeValues();
}
if (ClearingFault) {
......
/** Simulation
*
* @author Markus Mirz <mmirz@eonerc.rwth-aachen.de>
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
*
* 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 "MNA_Simulation.h"
#include "CPowerSystems/Source/CIM/Reader.h"
using namespace DPsim;
MnaSimulation::MnaSimulation(String name,
Component::List comps,
Real frequency, Real timeStep, Real finalTime, SimulationType simType,
Logger::Level logLevel, Int downSampleRate) :
mLog("Logs/" + name + ".log", logLevel),
mLeftVectorLog("Logs/" + name + "_LeftVector.csv", logLevel),
mRightVectorLog("Logs/" + name + "_RightVector.csv", logLevel) {
mGnd = std::make_shared<Node>(-1);
mName = name;
mTimeStep = timeStep;
mFinalTime = finalTime;
mSystemFrequency = frequency;
mSystemOmega = 2 * PI*frequency;
mSimType = simType;
mLogLevel = logLevel;
mDownSampleRate = downSampleRate;
initialize(comps);
// Logging
for (auto comp : comps)
mLog.Log(Logger::Level::INFO) << "Added " << comp->getType() << " '" << comp->getName() << "' to simulation." << std::endl;
mLog.Log(Logger::Level::INFO) << "System matrix:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mSystemMatrices[mSystemIndex]);
mLog.Log(Logger::Level::INFO) << "LU decomposition:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mLuFactorizations[mSystemIndex].matrixLU());
mLog.Log(Logger::Level::INFO) << "Right side vector:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mRightSideVector);
}
MnaSimulation::MnaSimulation(String name,
std::list<String> cimFiles,
Real frequency, Real timeStep, Real finalTime, SimulationType simType,
Logger::Level logLevel, Int downSampleRate) :
mLog("Logs/" + name + ".log", logLevel),
mLeftVectorLog("Logs/" + name + "_LeftVector.csv", logLevel),
mRightVectorLog("Logs/" + name + "_RightVector.csv", logLevel) {
mGnd = std::make_shared<Node>(-1);
mName = name;
mTimeStep = timeStep;
mFinalTime = finalTime;
mSystemFrequency = frequency;
mSystemOmega = 2*PI*frequency;
mSimType = simType;
mLogLevel = logLevel;
mDownSampleRate = downSampleRate;
CIM::Reader reader(frequency, logLevel, logLevel);
for (String filename : cimFiles) {
if (!reader.addFile(filename))
std::cout << "Failed to read file " << filename << std::endl;
}
try {
reader.parseFiles();
}
catch (...) {
std::cerr << "Failed to parse CIM files" << std::endl;
return;
}
mNodes.push_back(reader.getNodes());
Component::List comps = reader.getComponents();
initialize(comps);
// Logging
for (auto comp : comps)
mLog.Log(Logger::Level::INFO) << "Added " << comp->getType() << " '" << comp->getName() << "' to simulation." << std::endl;
mLog.Log(Logger::Level::INFO) << "System matrix:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mSystemMatrices[mSystemIndex]);
mLog.Log(Logger::Level::INFO) << "LU decomposition:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mLuFactorizations[mSystemIndex].matrixLU());
mLog.Log(Logger::Level::INFO) << "Right side vector:" << std::endl;
mLog.LogMatrix(Logger::Level::INFO, mRightSideVector);
}
void MnaSimulation::initialize(Component::List newComponents) {
mComponents.push_back(newComponents);
mLog.Log(Logger::Level::INFO) << "#### Start Initialization ####" << std::endl;
// Calculate the mNumber of nodes by going through the list of components
// TODO we use the values from the first component vector right now and assume that
// these values don't change on switches
Int maxNode = 0;
for (auto comp : mComponents[mSystemIndex]) {
// determine maximum node in component list
if (comp->getNode1() > maxNode)
maxNode = comp->getNode1();
if (comp->getNode2() > maxNode)
maxNode = comp->getNode2();
}
if (mNodes[mSystemIndex].size() == 0) {
// Create Nodes for all node indices
mNodes.push_back(Node::List(maxNode + 1, nullptr));
for (int node = 0; node < mNodes.size(); node++)
mNodes[mSystemIndex][node] = std::make_shared<Node>(node);
for (auto comp : mComponents[mSystemIndex]) {
std::shared_ptr<Node> node1, node2;
if (comp->getNode1() < 0)
node1 = mGnd;
else
node1 = mNodes[mSystemIndex][comp->getNode1()];
if (comp->getNode2() < 0)
node2 = mGnd;
else
node2 = mNodes[mSystemIndex][comp->getNode2()];
comp->setNodes(Node::List{ node1, node2 });
}
}
mLog.Log(Logger::Level::INFO) << "Maximum node number: " << maxNode << std::endl;
// virtual nodes are placed after network nodes
UInt virtualNode = maxNode;
// Check if component requires virtual node and if so set one
for (auto comp : mComponents[mSystemIndex]) {
if (comp->hasVirtualNodes()) {
for (Int node = 0; node < comp->getVirtualNodesNum(); node++) {
virtualNode++;
mNodes[mSystemIndex].push_back(std::make_shared<Node>(virtualNode));
comp->setVirtualNodeAt(mNodes[mSystemIndex][virtualNode], node);
mLog.Log(Logger::Level::INFO) << "Created virtual node" << node << "= " << virtualNode
<< " for " << comp->getName() << std::endl;
}
}
}
// Calculate system size and create matrices and vectors
mNumNodes = virtualNode + 1;
createEmptyVectors();
createEmptySystemMatrix();
// Initialize right side vector and components
mLog.Log(Logger::Level::INFO) << "Initialize power flow" << std::endl;
for (auto comp : newComponents) {
comp->initializePowerflow(mSystemFrequency);
comp->mnaInitialize(mSystemOmega, mTimeStep);
comp->mnaApplyRightSideVectorStamp(mRightSideVector);
comp->mnaApplySystemMatrixStamp(mSystemMatrices[mSystemIndex]);
}
// Compute LU-factorization for system matrix
mLuFactorizations.push_back(Eigen::PartialPivLU<Matrix>(mSystemMatrices[mSystemIndex]));
}
void MnaSimulation::createEmptyVectors() {
if (mSimType == SimulationType::EMT) {
mRightSideVector = Matrix::Zero(mNumNodes, 1);
mLeftSideVector = Matrix::Zero(mNumNodes, 1);
}
else {
mRightSideVector = Matrix::Zero(2 * mNumNodes, 1);
mLeftSideVector = Matrix::Zero(2 * mNumNodes, 1);
}
}
void MnaSimulation::createEmptySystemMatrix() {
if (mSimType == SimulationType::EMT) {
mSystemMatrices.push_back(Matrix::Zero(mNumNodes, mNumNodes));
}
else {
mSystemMatrices.push_back(Matrix::Zero(2 * mNumNodes, 2 * mNumNodes));
}
}
void MnaSimulation::addSystemTopology(Component::List newComponents) {
mComponents.push_back(newComponents);
// It is assumed that the system size does not change
createEmptySystemMatrix();
for (auto comp : newComponents)
comp->mnaApplySystemMatrixStamp(mSystemMatrices[mSystemMatrices.size()]);
mLuFactorizations.push_back(LUFactorized(mSystemMatrices[mSystemMatrices.size()]));
}
void MnaSimulation::switchSystemMatrix(Int systemIndex) {
if (systemIndex < mSystemMatrices.size())
mSystemIndex = systemIndex;
}
void MnaSimulation::solve() {
mLeftSideVector = mLuFactorizations[mSystemIndex].solve(mRightSideVector);
}
Int MnaSimulation::step(bool blocking) {
mRightSideVector.setZero();
for (auto eif : mExternalInterfaces) {
eif->readValues(blocking);
}
for (auto comp : mComponents[mSystemIndex]) {
comp->mnaStep(mSystemMatrices[mSystemIndex], mRightSideVector, mLeftSideVector, mTime);
}
solve();
for (auto comp : mComponents[mSystemIndex]) {
comp->mnaPostStep(mRightSideVector, mLeftSideVector, mTime);
}
for (auto eif : mExternalInterfaces) {
eif->writeValues();
}
if (mSwitchTimeIndex < mSwitchEvents.size()) {
if (mTime >= mSwitchEvents[mSwitchTimeIndex].switchTime) {
switchSystemMatrix(mSwitchEvents[mSwitchTimeIndex].systemIndex);
++mSwitchTimeIndex;
mLog.Log(Logger::Level::INFO) << "Switched to system " << mSwitchTimeIndex << " at " << mTime << std::endl;
mLog.Log(Logger::Level::INFO) << "New matrix:" << std::endl << mSystemMatrices[mSystemIndex] << std::endl;
mLog.Log(Logger::Level::INFO) << "New decomp:" << std::endl << mLuFactorizations[mSystemIndex].matrixLU() << std::endl;
}
}
mLeftVectorLog.LogNodeValues(getTime(), getLeftSideVector());
mRightVectorLog.LogNodeValues(getTime(), getRightSideVector());
return mTime < mFinalTime;
}
void MnaSimulation::run() {
mLog.Log(Logger::Level::INFO) << "Start simulation." << std::endl;
while (step()) {
increaseByTimeStep();
}
mLog.Log(Logger::Level::INFO) << "Simulation finished." << std::endl;
}
void MnaSimulation::run(double duration) {
mLog.Log(Logger::Level::INFO) << "Run simulation for " << duration << " seconds." << std::endl;
double started = mTime;
while (step()) {
increaseByTimeStep();
if (mTime - started > duration)
break;
}
mLog.Log(Logger::Level::INFO) << "Simulation finished." << std::endl;
}
void MnaSimulation::setSwitchTime(Real switchTime, Int systemIndex) {
SwitchConfiguration newSwitchConf;
newSwitchConf.switchTime = switchTime;
newSwitchConf.systemIndex = systemIndex;
mSwitchEvents.push_back(newSwitchConf);
}
/** Simulation
*
* @author Markus Mirz <mmirz@eonerc.rwth-aachen.de>
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
*
* 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/>.
*********************************************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <list>
#include "CPowerSystems/Source/Definitions.h"
#include "CPowerSystems/Source/Component.h"
#include "CPowerSystems/Source/Logger.h"
#include "CPowerSystems/Source/Interfaces/ExternalInterface.h"
#include "CPowerSystems/Source/Node.h"
namespace DPsim {
/// Ground node
const Int GND = -1;
/// Holds switching time and which system should be activated.
struct SwitchConfiguration {
Real switchTime;
UInt systemIndex;
};
/// Simulation class which uses Modified Nodal Analysis (MNA).
class MnaSimulation {
protected:
/// Simulation name
String mName;
// General simulation settings
/// Final time of the simulation
Real mFinalTime;
/// Time variable that is incremented at every step
Real mTime = 0;
/// system frequency
Real mSystemFrequency;
/// System angular frequency - omega
Real mSystemOmega;
/// Simulation time step
Real mTimeStep;
/// Simulation type, which can be dynamic phasor (DP) or EMT
SimulationType mSimType;
/// Ground node
Node::Ptr mGnd;
/// Number of nodes
UInt mNumNodes = 0;
/// Vector of ExternalInterfaces
std::vector<ExternalInterface*> mExternalInterfaces;
/// Flag to activate power flow based initialization.