Commit 8042a16f authored by Georg Martin Reinke's avatar Georg Martin Reinke
Browse files

first work on VILLAS shmem interface

parent c43efaae
#include "ExternalVoltageSource.h"
using namespace DPsim;
ExternalVoltageSource::ExternalVoltageSource(std::string name, int src, int dest, Real voltage, Real phase, int num): IdealVoltageSource(name, src, dest, voltage, phase, num) {
this->mPhase = phase;
}
void ExternalVoltageSource::setVoltage(Real voltage) {
this->mVoltageDiffr = voltage*cos(mPhase);
this->mVoltageDiffi = voltage*sin(mPhase);
}
#pragma once
#include "IdealVoltageSource.h"
namespace DPsim {
/** Ideal voltage source, but the voltage value can be changed between simulation
* steps (for example for interfacing with another simulator) */
class ExternalVoltageSource : public IdealVoltageSource {
private:
Real mPhase;
public:
ExternalVoltageSource() {};
ExternalVoltageSource(std::string name, int src, int dest, Real voltage, Real phase, int num);
void setVoltage(Real voltage);
};
}
......@@ -4,6 +4,7 @@
#include "Examples/SynchronGenUnitTest.h"
#include "Examples/SimpleCircuitTest.h"
#include "Examples/ReferenceCircuits.h"
#include "Examples/VillasTest.h"
#include <complex>
using namespace DPsim;
......@@ -12,15 +13,16 @@ int main(int argc, char* argv[]) {
simulationExample1();
simulationExample2();
simulationExample3();
simulationExampleIdealVS();
simulationExampleIdealVS2();
simulationExampleIdealVS3();
simulationExampleRXLine3();
simulationExampleRXLine();
simulationExampleRXLine2();
villasExample();
//simulationExample1();
//simulationExample2();
//simulationExample3();
//simulationExampleIdealVS();
//simulationExampleIdealVS2();
//simulationExampleIdealVS3();
//simulationExampleRXLine3();
//simulationExampleRXLine();
//simulationExampleRXLine2();
//NetlistSim(argc, argv);
......
......@@ -3,7 +3,7 @@
#include "../MathLibrary.h"
namespace Dpsim {
namespace DPsim {
// EMT generator tests
void SynGenUnitTestBalancedResLoad();
void SynGenUnitTestPhaseToPhaseFault();
......
#include "VillasTest.h"
#include "../Simulation.h"
#include "../VillasInterface.h"
#include "../Utilities.h"
using namespace DPsim;
void DPsim::villasExample()
{
// Very simple test circuit. Just 2 resistors and a voltage read from VILLASnode.
Logger log, llog, rlog;
std::vector<BaseComponent*> comps;
ExternalVoltageSource *evs = new ExternalVoltageSource("v1", 1, 0, 5, 0, 1);
comps.push_back(evs);
comps.push_back(new LinearResistor("r1", 1, 2, 1));
comps.push_back(new LinearResistor("r2", 2, 0, 1));
VillasInterface *villas = new VillasInterface("/villas1");
villas->registerVoltageSource(evs, 0);
std::cout << "The contents of circElements0 are:";
for (std::vector<BaseComponent*>::iterator it = comps.begin(); it != comps.end(); ++it) {
std::cout << "Added " << (*it)->getName() << std::endl;
}
std::cout << '\n';
// Set up simulation
Real timeStep = 0.01;
Simulation newSim(comps, 2.0*M_PI*50.0, timeStep, 0.1, log);
newSim.addExternalInterface(villas);
// Main Simulation Loop
std::cout << "Start simulation." << std::endl;
while (newSim.step(log, llog, rlog))
{
newSim.increaseByTimeStep();
updateProgressBar(newSim.getTime(), newSim.getFinalTime());
}
std::cout << "Simulation finished." << std::endl;
villas->shutdown();
log.WriteLogToFile("output.log");
rlog.WriteLogToFile("rvector.log");
llog.WriteLogToFile("lvector.log");
}
#ifndef VILLASTEST_H
#define VILLASTEST_H
namespace DPsim {
void villasExample();
}
#endif
#pragma once
namespace DPsim {
/** 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
* methods implemented by the subclass. Subclasses must also implement the
* readValues method, which should update the values of the registered
* components.
*/
class ExternalInterface {
public:
virtual void readValues() = 0;
};
}
# Declaration of variables
CC = g++
CC_FLAGS = -ggdb -w -lm -std=c++11 $(INCLUDES)
CC_FLAGS = -ggdb -w -std=c++11 $(INCLUDES)
LD_FLAGS = -lvillas-ext
# File names
EXEC = DPSolver
SOURCES = $(wildcard *.cpp) $(wildcard Components/*.cpp)
SOURCES = $(wildcard *.cpp) $(wildcard Components/*.cpp) $(wildcard Examples/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
INCLUDES = -I /usr/local/include/eigen
INCLUDES = -I /usr/include/eigen3
# Main target
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
$(CC) $(OBJECTS) $(LD_FLAGS) -o $(EXEC)
# To obtain object files
%.o: %.cpp
......
......@@ -62,10 +62,10 @@ void Simulation::initialize(std::vector<BaseComponent*> newElements) {
}
std::string type = typeid(*(*it)).name();
if (type == "class DPsim::IdealVoltageSource") {
if (dynamic_cast<IdealVoltageSource*>(*it)) {
numIdealVS = numIdealVS + 1;
}
if (type == "class DPsim::RxLine") {
if (dynamic_cast<RxLine*>(*it)) {
if ((*it)->getNode3() != -1) {
numRxLines = numRxLines + 1;
}
......@@ -106,7 +106,11 @@ void Simulation::addSystemTopology(std::vector<BaseComponent*> newElements) {
int Simulation::step(Logger& logger)
{
mSystemModel.setRightSideVectorToZero(getRightSideVector());
mSystemModel.setRightSideVectorToZero();
for (auto it = mExternalInterfaces.begin(); it != mExternalInterfaces.end(); ++it) {
(*it)->readValues();
}
for (std::vector<BaseComponent*>::iterator it = mElements.begin(); it != mElements.end(); ++it) {
(*it)->step(mSystemModel, mTime);
......@@ -222,3 +226,7 @@ void Simulation::setSwitchTime(Real switchTime, Int systemIndex) {
void Simulation::increaseByTimeStep() {
mTime = mTime + mSystemModel.getTimeStep();
}
void Simulation::addExternalInterface(ExternalInterface *eint) {
this->mExternalInterfaces.push_back(eint);
}
......@@ -7,6 +7,7 @@
#include "Components.h"
#include "Logger.h"
#include "SystemModel.h"
#include "ExternalInterface.h"
namespace DPsim {
......@@ -32,6 +33,9 @@ namespace DPsim {
/// Circuit list vector
std::vector<std::vector<BaseComponent*> > mElementsVector;
/// Vector of ExternalInterfaces
std::vector<ExternalInterface*> mExternalInterfaces;
/// TODO: check that every system matrix has the same dimensions
void initialize(std::vector<BaseComponent*> elements);
......@@ -55,6 +59,7 @@ namespace DPsim {
void switchSystemMatrix(int systemMatrixIndex);
void setSwitchTime(Real switchTime, Int systemIndex);
void increaseByTimeStep();
void addExternalInterface(ExternalInterface*);
double getTime() { return mTime; }
double getFinalTime() { return mFinalTime; }
......
......@@ -65,6 +65,6 @@ void SystemModel::switchSystemMatrix(Int systemMatrixIndex) {
}
}
void SystemModel::setRightSideVectorToZero(DPsim::Matrix& rightSideVector) {
void SystemModel::setRightSideVectorToZero() {
mRightSideVector.setZero();
}
......@@ -70,7 +70,7 @@ namespace DPsim {
void addCompToSystemMatrix(Int row, Int column, Real reValue, Real imValue);
void addCompToRightSideVector(Int row, Real reValue, Real imValue);
void addRealToRightSideVector(Int row, Real value);
void setRightSideVectorToZero(DPsim::Matrix& rightSideVector);
void setRightSideVectorToZero();
void solve();
};
......
#include <cstdio>
#include <cstdlib>
#include <villas/sample.h>
#include <villas/shmem.h>
#include "VillasInterface.h"
using namespace DPsim;
VillasInterface::VillasInterface(const char* name) {
this->mShmemName = name;
mShmem = shmem_shared_open(name, &this->mBase);
if (!mShmem) {
std::perror("Failed to open/map shared memory object");
std::exit(1);
}
}
void VillasInterface::registerVoltageSource(ExternalVoltageSource *evs, int num) {
mExtComponents[num] = evs;
}
void VillasInterface::readValues() {
struct sample *sample;
int ret = 0;
while (ret == 0)
ret = shmem_shared_read(mShmem, &sample, 1);
if (ret < 0) {
std::cerr << "Fatal error: failed to read sample from shmem interface" << std::endl;
std::exit(1);
}
for (auto it = mExtComponents.begin(); it != mExtComponents.end(); ++it) {
if (sample->length <= it->first) {
std::cerr << "Warning: missing data in received sample" << std::endl;
continue;
}
// TODO integer format?
ExternalVoltageSource *evs = dynamic_cast<ExternalVoltageSource*>(it->second);
if (evs)
evs->setVoltage(sample->data[0].f);
// TODO other classes
sample_put(sample);
}
}
// TODO put this in destructor
void VillasInterface::shutdown() {
shmem_shared_close(mShmem, mBase);
}
#pragma once
#include <atomic>
#include <unordered_map>
#include <villas/shmem.h>
#include "ExternalInterface.h"
#include "Components/ExternalVoltageSource.h"
namespace DPsim {
/** Implements ExternalInterface by using the shared memory interface of VILLASnode. */
class VillasInterface : public ExternalInterface {
private:
const char* mShmemName;
struct shmem_shared* mShmem;
void* mBase;
std::unordered_map<int, BaseComponent*> mExtComponents;
public:
VillasInterface(const char* name);
void registerVoltageSource(ExternalVoltageSource* evs, int num);
virtual void readValues();
void shutdown();
};
};
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