Commit 1b15c005 authored by Niklas Eiling's avatar Niklas Eiling
Browse files

Make Simulation class able to choose MNASolver implementation during runtime.



Modify CommandLineArgs to parse new argument "-U" which sets the MNASolver implementation to use.
Modify WSCC_coupled example to use the new parser implementation.
Signed-off-by: Niklas Eiling's avatarNiklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
parent 792eb70e
......@@ -65,22 +65,19 @@ void multiply_connected(SystemTopology& sys, int copies,
}
}
void simulateCoupled(std::list<fs::path> filenames, Int copies, Int threads, Int seq = 0, Logger::Level logLevel = Logger::Level::off) {
void simulateCoupled(std::list<fs::path> filenames, CommandLineArgs& args, Int copies, Int threads, Int seq = 0) {
String simName = "WSCC_9bus_coupled_" + std::to_string(copies)
+ "_" + std::to_string(threads) + "_" + std::to_string(seq);
Logger::setLogDir("logs/"+simName);
CIM::Reader reader(simName, logLevel, logLevel);
CIM::Reader reader(simName, args.logLevel, args.logLevel);
SystemTopology sys = reader.loadCIM(60, filenames);
if (copies > 0)
multiply_connected(sys, copies, 12.5, 0.16, 1e-6);
Simulation sim(simName, logLevel);
Simulation sim(simName, args);
sim.setSystem(sys);
sim.setTimeStep(0.0001);
sim.setFinalTime(0.5);
sim.setDomain(Domain::DP);
if (threads > 0)
sim.setScheduler(std::make_shared<OpenMPLevelScheduler>(threads));
......@@ -105,6 +102,10 @@ void simulateCoupled(std::list<fs::path> filenames, Int copies, Int threads, Int
int main(int argc, char *argv[]) {
CommandLineArgs args(argc, argv);
args.timeStep = 0.0001;
args.duration = 0.5;
args.solver.domain = Domain::DP;
args.solver.type = Solver::Type::MNA;
std::list<fs::path> filenames;
filenames = DPsim::Utils::findFiles({
......@@ -122,6 +123,6 @@ int main(int argc, char *argv[]) {
std::cout << "Simulate with " << Int(args.options["copies"]) << " copies, "
<< Int(args.options["threads"]) << " threads, sequence number "
<< Int(args.options["seq"]) << std::endl;
simulateCoupled(filenames, Int(args.options["copies"]),
Int(args.options["threads"]), Int(args.options["seq"]), args.logLevel);
simulateCoupled(filenames, args, Int(args.options["copies"]),
Int(args.options["threads"]), Int(args.options["seq"]));
}
......@@ -9,6 +9,7 @@
#pragma once
#include <dpsim/MNASolver.h>
#include <dpsim/DataLogger.h>
#include <dpsim/MNASolverEigenDense.h>
#ifdef WITH_SPARSE
#include <dpsim/MNASolverEigenSparse.h>
......@@ -27,6 +28,7 @@ class MnaSolverFactory {
/// \brief The implementations of the MNA solvers MnaSolver can support.
///
enum MnaSolverImpl {
Undef = 0,
EigenDense,
EigenSparse,
CUDADense,
......@@ -57,18 +59,28 @@ class MnaSolverFactory {
CPS::Logger::Level logLevel = CPS::Logger::Level::info,
MnaSolverImpl implementation = mSupportedSolverImpls().back())
{
//To avoid regression we use EigenDense in case of undefined implementation
if (implementation == MnaSolverImpl::Undef) {
implementation = MnaSolverImpl::EigenDense;
}
CPS::Logger::Log log = CPS::Logger::get("MnaSolverFactory", CPS::Logger::Level::info, CPS::Logger::Level::info);
switch(implementation) {
case MnaSolverImpl::EigenDense:
log->info("creating EigenDense solver implementation");
return std::make_shared<MnaSolverEigenDense<VarType>>(name, domain, logLevel);
#ifdef WITH_SPARSE
case MnaSolverImpl::EigenSparse:
log->info("creating EigenSparse solver implementation");
return std::make_shared<MnaSolverEigenSparse<VarType>>(name, domain, logLevel);
#endif
#ifdef WITH_CUDA
case MnaSolverImpl::CUDADense:
log->info("creating CUDADense solver implementation");
return std::make_shared<MnaSolverGpuDense<VarType>>(name, domain, logLevel);
#ifdef WITH_SPARSE
case MnaSolverImpl::CUDASparse:
log->info("creating CUDASparse solver implementation");
return std::make_shared<MnaSolverGpuSparse<VarType>>(name, domain, logLevel);
#endif
#endif
......
......@@ -8,6 +8,7 @@
#pragma once
#include "dpsim/MNASolverFactory.h"
#include <vector>
#include <dpsim/Config.h>
......@@ -20,6 +21,7 @@
#include <cps/SystemTopology.h>
#include <cps/SimNode.h>
#include <dpsim/Interface.h>
#include <dpsim/Utils.h>
#ifdef WITH_GRAPHVIZ
#include <cps/Graph.h>
......@@ -63,6 +65,8 @@ namespace DPsim {
///
Solver::List mSolvers;
///
MnaSolverFactory::MnaSolverImpl mMnaImpl = MnaSolverFactory::MnaSolverImpl::Undef;
///
Bool mInitFromNodesAndTerminals = true;
/// Enable recomputation of system matrix during simulation
Bool mSystemMatrixRecomputation = false;
......@@ -143,6 +147,9 @@ namespace DPsim {
/// Simulation logger
CPS::Logger::Log mLog;
/// Creates simulation with name and CommandLineArgs
Simulation(String name, CommandLineArgs& args);
/// Creates simulation with name and log level
Simulation(String name, CPS::Logger::Level logLevel = CPS::Logger::Level::info);
......
......@@ -23,6 +23,7 @@
#include <dpsim/Timer.h>
#include <dpsim/Solver.h>
#include <cps/Logger.h>
#include <dpsim/MNASolverFactory.h>
namespace fs = std::experimental::filesystem;
......@@ -56,7 +57,8 @@ public:
Bool b = false,
Bool si = false,
CPS::Domain sd = CPS::Domain::DP,
Solver::Type st = Solver::Type::MNA
Solver::Type st = Solver::Type::MNA,
MnaSolverFactory::MnaSolverImpl mi = MnaSolverFactory::mSupportedSolverImpls().back()
);
void showUsage();
......@@ -78,6 +80,7 @@ public:
CPS::Domain domain;
Solver::Type type;
} solver;
DPsim::MnaSolverFactory::MnaSolverImpl mnaImpl;
DPsim::Timer::StartClock::time_point startTime;
......
......@@ -45,6 +45,31 @@
using namespace CPS;
using namespace DPsim;
Simulation::Simulation(String name, CommandLineArgs& args) :
mName(name),
mFinalTime(args.duration),
mTimeStep(args.timeStep),
mLogLevel(args.logLevel),
mDomain(args.solver.domain),
mSolverType(args.solver.type),
mMnaImpl(args.mnaImpl)
{
addAttribute<String>("name", &mName, Flags::read);
addAttribute<Real>("time_step", &mTimeStep, Flags::read);
addAttribute<Real>("final_time", &mFinalTime, Flags::read|Flags::write);
addAttribute<Bool>("steady_state_init", &mSteadyStateInit, Flags::read|Flags::write);
addAttribute<Bool>("split_subnets", &mSplitSubnets, Flags::read|Flags::write);
addAttribute<Real>("time_step", &mTimeStep, Flags::read);
Eigen::setNbThreads(1);
// Logging
mLog = Logger::get(name, mLogLevel, std::max(Logger::Level::info, mLogLevel));
mInitialized = false;
}
Simulation::Simulation(String name, Logger::Level logLevel) :
mName(name), mLogLevel(logLevel) {
......@@ -190,7 +215,7 @@ void Simulation::createMNASolver() {
else {
// Default case with precomputed system matrices for different configurations
solver = MnaSolverFactory::factory<VarType>(mName + copySuffix, mDomain,
mLogLevel);
mLogLevel, mMnaImpl);
solver->setTimeStep(mTimeStep);
solver->doSteadyStateInit(mSteadyStateInit);
solver->doFrequencyParallelization(mFreqParallel);
......
......@@ -6,6 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*********************************************************************************/
#include "dpsim/MNASolverFactory.h"
#include <string>
#include <dpsim/Config.h>
......@@ -32,7 +33,8 @@ CommandLineArgs::CommandLineArgs(int argc, char *argv[],
Bool b,
Bool si,
CPS::Domain sd,
Solver::Type st
Solver::Type st,
MnaSolverFactory::MnaSolverImpl mi
) :
mProgramName(argv[0]),
mArguments {
......@@ -49,6 +51,7 @@ CommandLineArgs::CommandLineArgs(int argc, char *argv[],
{ "start-in", required_argument, 0, 'i', "SECS", "" },
{ "solver-domain", required_argument, 0, 'D', "(SP|DP|EMT)", "Domain of solver" },
{ "solver-type", required_argument, 0, 'T', "(NRP|MNA)", "Type of solver" },
{ "solver-mna-impl", required_argument, 0, 'U', "(EigenDense|EigenSparse|CUDADense|CUDASparse)", "Type of MNA Solver implementation"},
{ "option", required_argument, 0, 'o', "KEY=VALUE", "User-definable options" },
{ "name", required_argument, 0, 'n', "NAME", "Name of log files" },
{ 0 }
......@@ -62,7 +65,8 @@ CommandLineArgs::CommandLineArgs(int argc, char *argv[],
startSynch(ss),
blocking(b),
steadyInit(si),
solver{sd, st}
solver{sd, st},
mnaImpl(mi)
{
std::vector<option> long_options;
for (auto a : mArguments)
......@@ -73,7 +77,7 @@ CommandLineArgs::CommandLineArgs(int argc, char *argv[],
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long(argc, argv, "ht:d:s:l:a:i:f:D:T:o:Sbn:", long_options.data(), &option_index);
c = getopt_long(argc, argv, "ht:d:s:l:a:i:f:D:T:U:o:Sbn:", long_options.data(), &option_index);
/* Detect the end of the options. */
if (c == -1)
......@@ -180,6 +184,21 @@ CommandLineArgs::CommandLineArgs(int argc, char *argv[],
throw std::invalid_argument("Invalid value for --solver-type: must be a string of NRP or MNA");
break;
}
case 'U': {
String arg = optarg;
if (arg == "EigenDense") {
mnaImpl = MnaSolverFactory::EigenDense;
} else if (arg == "EigenSparse") {
mnaImpl = MnaSolverFactory::EigenSparse;
} else if (arg == "CUDADense") {
mnaImpl = MnaSolverFactory::CUDADense;
} else if (arg == "CUDASparse") {
mnaImpl = MnaSolverFactory::CUDASparse;
} else {
throw std::invalid_argument("Invalid value for --solver-mna-impl");
}
break;
}
case 'i': {
double deltaT = std::stod(optarg);
......
Markdown is supported
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