Skip to content

Commit

Permalink
New queueless VILLAS interface / improve real-time performance (#316)
Browse files Browse the repository at this point in the history
 villas interface: improve real-time capability

The original villas interface was not real-time capable because of the
queue it uses. This commit creates an interface for villas interfaces,
moves the old implementation to InterfaceQueued and adds a new
queueless, threadless implementation InterfaceQueueless.


models: Add DC voltage source

The DP_Ph1_VoltageSource always calculates a sinusoidal signal, even if
we only want to set a DC value. This commit adds a DC generator for the
model so it can be significantly faster if we do not need the sinusoidal
signal.

 FpgaExample: use new villas interface and make logging optional.
  • Loading branch information
m-mirz authored Nov 8, 2024
2 parents d66f826 + de97ebb commit ad81d7e
Show file tree
Hide file tree
Showing 30 changed files with 1,423 additions and 365 deletions.
6 changes: 3 additions & 3 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
---
BasedOnStyle: LLVM

# Disable automatic line-breaks in comments
# as this breaks SPDX headers
ReflowComments: false
# Increase ColumnLimit to avoid breaking SPDX headers
ColumnLimit: 200

1 change: 1 addition & 0 deletions dpsim-models/include/dpsim-models/Attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ class Attribute : public AttributeBase,
AttributeBase::Ptr cloneValueOntoNewAttribute() override {
return AttributePointer<AttributeBase>(
AttributeStatic<T>::make(this->get()));
// TODO: This is in the real time path. We should not use heap here.
};

/**
Expand Down
111 changes: 111 additions & 0 deletions dpsim-models/include/dpsim-models/DP/DP_Ph1_ProfileVoltageSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* Voltage Source that reads references from a file and replays them.
*
* Author: Niklas Eiling <[email protected]>
* SPDX-FileCopyrightText: 2024 Niklas Eiling <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Signal/CosineFMGenerator.h>
#include <dpsim-models/Signal/DCGenerator.h>
#include <dpsim-models/Signal/FrequencyRampGenerator.h>
#include <dpsim-models/Signal/SignalGenerator.h>
#include <dpsim-models/Signal/SineWaveGenerator.h>
#include <dpsim-models/Solver/DAEInterface.h>
#include <dpsim-models/Solver/MNAInterface.h>
#include <filesystem>
#include <villas/sample.hpp>

namespace CPS {
namespace DP {
namespace Ph1 {

class ProfileVoltageSource : public MNASimPowerComp<Complex>, public DAEInterface, public SharedFactory<ProfileVoltageSource> {
private:
///
void updateVoltage(Real time);
///
// CPS::Signal::SignalGenerator::Ptr mSrcSig;
std::filesystem::path mSourceFile;
size_t mSourceIndex = 0;
std::vector<double> mSamples;

void readFromFile();

public:
const CPS::Attribute<Complex>::Ptr mVoltage;

/// Defines UID, name, component parameters and logging level
ProfileVoltageSource(String uid, String name, std::filesystem::path sourceFile, Logger::Level loglevel = Logger::Level::off);
/// Defines UID, name, component parameters and logging level
ProfileVoltageSource(String name, std::filesystem::path sourceFile, Logger::Level logLevel = Logger::Level::off) : ProfileVoltageSource(name, name, sourceFile, logLevel) {}
///
SimPowerComp<Complex>::Ptr clone(String name) override;

// #### General ####
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency) override;
///
void setSourceFile(std::filesystem::path file, size_t index = 0);

// #### MNA Section ####
/// Initializes internal variables of the component
void mnaCompInitialize(Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) override;
void mnaCompInitializeHarm(Real omega, Real timeStep, std::vector<Attribute<Matrix>::Ptr> leftVectors) override;
/// Stamps system matrix
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override;
void mnaCompApplySystemMatrixStampHarm(SparseMatrixRow &systemMatrix, Int freqIdx) override;
/// Stamps right side (source) vector
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
void mnaCompApplyRightSideVectorStampHarm(Matrix &rightVector) override;
/// Returns current through the component
void mnaCompUpdateCurrent(const Matrix &leftVector) override;
/// MNA pre step operations
void mnaCompPreStep(Real time, Int timeStepCount) override;
/// MNA post step operations
void mnaCompPostStep(Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) override;
/// Add MNA pre step dependencies
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override;
/// Add MNA post step dependencies
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes,
Attribute<Matrix>::Ptr &leftVector) override;

class MnaPreStepHarm : public CPS::Task {
public:
MnaPreStepHarm(ProfileVoltageSource &voltageSource) : Task(**voltageSource.mName + ".MnaPreStepHarm"), mVoltageSource(voltageSource) {
mAttributeDependencies.push_back(mVoltageSource.mVoltage);
mModifiedAttributes.push_back(mVoltageSource.mRightVector);
mModifiedAttributes.push_back(mVoltageSource.mIntfVoltage);
}
void execute(Real time, Int timeStepCount);

private:
ProfileVoltageSource &mVoltageSource;
};

class MnaPostStepHarm : public CPS::Task {
public:
MnaPostStepHarm(ProfileVoltageSource &voltageSource, const std::vector<Attribute<Matrix>::Ptr> &leftVectors)
: Task(**voltageSource.mName + ".MnaPostStepHarm"), mVoltageSource(voltageSource), mLeftVectors(leftVectors) {
for (UInt i = 0; i < mLeftVectors.size(); i++)
mAttributeDependencies.push_back(mLeftVectors[i]);
mModifiedAttributes.push_back(mVoltageSource.mIntfCurrent);
}
void execute(Real time, Int timeStepCount);

private:
ProfileVoltageSource &mVoltageSource;
std::vector<Attribute<Matrix>::Ptr> mLeftVectors;
};

// #### DAE Section ####
/// Residual function for DAE Solver
void daeResidual(double ttime, const double state[], const double dstate_dt[], double resid[], std::vector<int> &off) override;
/// Voltage Getter
Complex daeInitialize() override;
};
} // namespace Ph1
} // namespace DP
} // namespace CPS
5 changes: 5 additions & 0 deletions dpsim-models/include/dpsim-models/DP/DP_Ph1_VoltageSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Signal/CosineFMGenerator.h>
#include <dpsim-models/Signal/DCGenerator.h>
#include <dpsim-models/Signal/FrequencyRampGenerator.h>
#include <dpsim-models/Signal/SignalGenerator.h>
#include <dpsim-models/Signal/SineWaveGenerator.h>
Expand Down Expand Up @@ -79,6 +80,10 @@ class VoltageSource : public MNASimPowerComp<Complex>,
void setParameters(Complex initialPhasor, Real modulationFrequency,
Real modulationAmplitude, Real baseFrequency = 0.0,
bool zigzag = false);
/// Setter for reference voltage with a real valued generator
/// This will initialize the values of mVoltageRef to match the given parameters
/// However, the attributes can be modified during the simulation to dynamically change the value of the output voltage.
void setParameters(Real voltageRef);

// #### MNA Section ####
/// Initializes internal variables of the component
Expand Down
30 changes: 30 additions & 0 deletions dpsim-models/include/dpsim-models/Signal/DCGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* Copyright 2014 Institute for Automation of Complex Power Systems,
* EONERC, RWTH Aachen University
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*********************************************************************************/

#pragma once

#include <dpsim-models/Signal/SignalGenerator.h>

namespace CPS {
namespace Signal {
/// \brief Model to generate sinusoidal signals
///
/// Inherits from the abstract SignalGenerator class.
/// The generated signal must be characterised by its initial complex phasor and its frequency.
class DCGenerator : public SignalGenerator, public SharedFactory<DCGenerator> {
public:
const Attribute<Complex>::Ptr mVoltageRef;
/// init the identified object
DCGenerator(String name, Logger::Level logLevel = Logger::Level::off);
/// set the source's parameters
void setParameters(Real initialReference = 0.0);
/// implementation of inherited method step to update and return the current signal value
void step(Real time);
};
} // namespace Signal
} // namespace CPS
6 changes: 6 additions & 0 deletions dpsim-models/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ list(APPEND MODELS_SOURCES
Signal/SignalGenerator.cpp
Signal/FrequencyRampGenerator.cpp
Signal/CosineFMGenerator.cpp
Signal/DCGenerator.cpp
)
list(APPEND MODELS_INCLUDE_DIRS "/home/eiling/projects/villas-node/build/lib/formats")

if(WITH_CIM)
list(APPEND MODELS_SOURCES CIM/Reader.cpp)
Expand All @@ -178,6 +180,10 @@ if(WITH_GSL)
list(APPEND MODELS_LIBRARIES ${GSL_LIBRARIES})
endif()

if(WITH_VILLAS)
list(APPEND MODELS_SOURCES DP/DP_Ph1_ProfileVoltageSource.cpp)
endif()

target_link_libraries(dpsim-models PUBLIC ${MODELS_LIBRARIES})
target_include_directories(dpsim-models PUBLIC ${MODELS_INCLUDE_DIRS})
target_sources(dpsim-models PRIVATE ${MODELS_SOURCES})
Expand Down
Loading

0 comments on commit ad81d7e

Please sign in to comment.