Commit fdb7d12b authored by Markus Mirz's avatar Markus Mirz
Browse files

MNASolver: refactoring tasks

parent 0cf3a1ce
......@@ -35,8 +35,7 @@ namespace DPsim {
template <typename VarType>
class MnaSolver : public Solver, public CPS::AttributeList {
protected:
// General simulation settings
// #### General simulation settings ####
/// Simulation domain, which can be dynamic phasor (DP) or EMT
CPS::Domain mDomain;
/// Number of nodes
......@@ -53,13 +52,12 @@ namespace DPsim {
UInt mNumVirtualMatrixNodeIndices = 0;
/// Number of harmonic nodes
UInt mNumHarmMatrixNodeIndices = 0;
/// Flag to activate power flow based initialization.
/// If this is false, all voltages are initialized with zero.
Bool mPowerflowInitialization;
/// System list
CPS::SystemTopology mSystem;
/// List of simulation nodes
typename CPS::SimNode<VarType>::List mNodes;
// #### MNA specific attributes ####
/// List of MNA components with static stamp into system matrix
CPS::MNAInterface::List mMNAComponents;
/// List of MNA components with extra functionality
......@@ -73,8 +71,6 @@ namespace DPsim {
/// List of signal type components that do not directly interact
/// with the MNA solver
CPS::SimSignalComp::List mSimSignalComps;
// #### MNA specific attributes ####
/// System matrix A that is modified by matrix stamps
std::bitset<SWITCH_NUM> mCurrentSwitchStatus;
/// Source vector of known quantities
......@@ -97,9 +93,9 @@ namespace DPsim {
// #### Dynamic matrix recomputation ####
/// Base matrix that includes all static MNA elements to speed up recomputation
Matrix mBaseSystemMatrix;
///
/// Flag that initiates recomputation of system matrix
Bool mUpdateSysMatrix;
///
/// Recomputes systems matrix
void updateSystemMatrix(Real time);
// #### Attributes related to switching ####
......@@ -148,23 +144,30 @@ namespace DPsim {
void updateVariableElementStatus();
/// Logging of system matrices and source vector
void logSystemMatrices();
// #### Scheduler Task Methods ####
/// Solves system for single frequency
void solve(Real time, Int timeStepCount);
/// Solves system for multiple frequencies
void solveWithHarmonics(Real time, Int timeStepCount, Int freqIdx);
/// Logs left and right vector
void log(Real time, Int timeStepCount);
public:
/// This constructor should not be called by users.
/// Constructor should not be called by users but by Simulation
MnaSolver(String name,
CPS::Domain domain = CPS::Domain::DP,
CPS::Logger::Level logLevel = CPS::Logger::Level::info);
///
/// Destructor
virtual ~MnaSolver() { };
///
void setSystem(CPS::SystemTopology system);
/// TODO: check that every system matrix has the same dimensions
/// Calls subroutines to set up everything that is required before simulation
void initialize();
/// Log left and right vector values for each simulation step
void log(Real time);
// #### Getter ####
// #### Setter and Getter ####
///
void setSystem(CPS::SystemTopology system);
///
Matrix& leftSideVector() { return mLeftSideVector; }
///
......@@ -172,19 +175,18 @@ namespace DPsim {
///
CPS::Task::List getTasks();
///
Matrix& systemMatrix() {
return mSwitchedMatrices[mCurrentSwitchStatus];
}
Matrix& systemMatrix() { return mSwitchedMatrices[mCurrentSwitchStatus]; }
// #### MNA Solver Tasks ####
///
class SolveTask : public CPS::Task {
public:
SolveTask(MnaSolver<VarType>& solver, Bool steadyStateInit) :
Task(solver.mName + ".Solve"), mSolver(solver), mSteadyStateInit(steadyStateInit) {
Task(solver.mName + ".Solve"), mSolver(solver) {
for (auto it : solver.mMNAComponents) {
if (it->template attribute<Matrix>("right_vector")->get().size() != 0) {
if (it->template attribute<Matrix>("right_vector")->get().size() != 0)
mAttributeDependencies.push_back(it->attribute("right_vector"));
}
}
for (auto node : solver.mNodes) {
mModifiedAttributes.push_back(node->attribute("v"));
......@@ -192,21 +194,21 @@ namespace DPsim {
mModifiedAttributes.push_back(solver.attribute("left_vector"));
}
void execute(Real time, Int timeStepCount);
void execute(Real time, Int timeStepCount) { mSolver.solve(time, timeStepCount); }
private:
MnaSolver<VarType>& mSolver;
Bool mSteadyStateInit;
};
///
class SolveTaskHarm : public CPS::Task {
public:
SolveTaskHarm(MnaSolver<VarType>& solver, Bool steadyStateInit, UInt freqIdx) :
Task(solver.mName + ".Solve"), mSolver(solver), mSteadyStateInit(steadyStateInit), mFreqIdx(freqIdx) {
Task(solver.mName + ".Solve"), mSolver(solver), mFreqIdx(freqIdx) {
for (auto it : solver.mMNAComponents) {
if (it->template attribute<Matrix>("right_vector")->get().size() != 0) {
if (it->template attribute<Matrix>("right_vector")->get().size() != 0)
mAttributeDependencies.push_back(it->attribute("right_vector"));
}
}
for (auto node : solver.mNodes) {
mModifiedAttributes.push_back(node->attribute("v"));
......@@ -216,11 +218,10 @@ namespace DPsim {
}
}
void execute(Real time, Int timeStepCount);
void execute(Real time, Int timeStepCount) { mSolver.solveWithHarmonics(time, timeStepCount, mFreqIdx); }
private:
MnaSolver<VarType>& mSolver;
Bool mSteadyStateInit;
UInt mFreqIdx;
};
......@@ -233,7 +234,7 @@ namespace DPsim {
mModifiedAttributes.push_back(Scheduler::external);
}
void execute(Real time, Int timeStepCount);
void execute(Real time, Int timeStepCount) { mSolver.log(time, timeStepCount); }
private:
MnaSolver<VarType>& mSolver;
......
......@@ -45,10 +45,13 @@ namespace DPsim {
Real mSteadStIniTimeLimit = 10;
/// steady state initialization accuracy limit
Real mSteadStIniAccLimit = 0.0001;
/// flag to activate steady state initialization
/// Activates steady state initialization
Bool mSteadyStateInit = false;
/// flag to activate powerflow initialization
/// Activates powerflow initialization
/// If this is false, all voltages are initialized with zero
Bool mPowerFlowInit = true;
/// Determines if solver is in initialization phase, which requires different behavior
Bool mIsInInitialization = false;
public:
typedef std::shared_ptr<Solver> Ptr;
......
......@@ -31,6 +31,7 @@ void MnaSolver<VarType>::setSystem(CPS::SystemTopology system) {
template <typename VarType>
void MnaSolver<VarType>::initialize() {
// TODO: check that every system matrix has the same dimensions
mSLog->info("---- Start initialization ----");
mSLog->info("-- Process topology");
......@@ -68,8 +69,11 @@ void MnaSolver<VarType>::initialize() {
// calculate MNA specific initialization values.
initializeComponents();
if (mSteadyStateInit)
if (mSteadyStateInit) {
mIsInInitialization = true;
steadyStateInitialization();
}
mIsInInitialization = false;
// Some components feature a different behaviour for simulation and initialization
for (auto comp : mSystem.mComponents) {
......@@ -617,52 +621,47 @@ Task::List MnaSolver<VarType>::getTasks() {
}
template <typename VarType>
void MnaSolver<VarType>::SolveTask::execute(Real time, Int timeStepCount) {
void MnaSolver<VarType>::solve(Real time, Int timeStepCount) {
// Reset source vector
mSolver.mRightSideVector.setZero();
mSolver.mUpdateSysMatrix = false;
mRightSideVector.setZero();
mUpdateSysMatrix = false;
// Add together the right side vector (computed by the components'
// pre-step tasks)
for (auto stamp : mSolver.mRightVectorStamps)
mSolver.mRightSideVector += *stamp;
for (auto stamp : mRightVectorStamps)
mRightSideVector += *stamp;
if (mSolver.mSwitchedMatrices.size() > 0)
mSolver.mLeftSideVector = mSolver.mLuFactorizations[mSolver.mCurrentSwitchStatus].solve(mSolver.mRightSideVector);
if (mSwitchedMatrices.size() > 0)
mLeftSideVector = mLuFactorizations[mCurrentSwitchStatus].solve(mRightSideVector);
// TODO split into separate task? (dependent on x, updating all v attributes)
for (UInt nodeIdx = 0; nodeIdx < mSolver.mNumNetNodes; nodeIdx++)
mSolver.mNodes[nodeIdx]->mnaUpdateVoltage(mSolver.mLeftSideVector);
for (UInt nodeIdx = 0; nodeIdx < mNumNetNodes; nodeIdx++)
mNodes[nodeIdx]->mnaUpdateVoltage(mLeftSideVector);
if (!mSteadyStateInit)
mSolver.updateSwitchStatus();
if ((mSolver.mVariableElements.size() > 0)) {
if (!mIsInInitialization) {
updateSwitchStatus();
mSolver.updateVariableElementStatus();
if (mSolver.mUpdateSysMatrix) {
mSolver.updateSystemMatrix(time);
}
updateVariableElementStatus();
if (mUpdateSysMatrix)
updateSystemMatrix(time);
}
// Components' states will be updated by the post-step tasks
}
template <typename VarType>
void MnaSolver<VarType>::SolveTaskHarm::execute(Real time, Int timeStepCount) {
mSolver.mRightSideVectorHarm[mFreqIdx].setZero();
void MnaSolver<VarType>::solveWithHarmonics(Real time, Int timeStepCount, Int freqIdx) {
mRightSideVectorHarm[freqIdx].setZero();
// Add together the right side vector (computed by the components'
// pre-step tasks)
for (auto stamp : mSolver.mRightVectorStamps)
mSolver.mRightSideVectorHarm[mFreqIdx] += stamp->col(mFreqIdx);
// Sum of right side vectors (computed by the components' pre-step tasks)
for (auto stamp : mRightVectorStamps)
mRightSideVectorHarm[freqIdx] += stamp->col(freqIdx);
mSolver.mLeftSideVectorHarm[mFreqIdx] =
mSolver.mLuFactorizationsHarm[mSolver.mCurrentSwitchStatus][mFreqIdx].solve(mSolver.mRightSideVectorHarm[mFreqIdx]);
mLeftSideVectorHarm[freqIdx] = mLuFactorizationsHarm[mCurrentSwitchStatus][freqIdx].solve(mRightSideVectorHarm[freqIdx]);
}
template <typename VarType>
void MnaSolver<VarType>::log(Real time) {
void MnaSolver<VarType>::log(Real time, Int timeStepCount) {
if (mLogLevel == Logger::Level::off)
return;
......@@ -710,11 +709,6 @@ void MnaSolver<VarType>::logSystemMatrices() {
}
}
template <typename VarType>
void MnaSolver<VarType>::LogTask::execute(Real time, Int timeStepCount) {
mSolver.log(time);
}
}
template class DPsim::MnaSolver<Real>;
......
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