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