19#include <spdlog/sinks/stdout_color_sinks.h>
75 Eigen::setNbThreads(1);
121 std::shared_ptr<PFSolver> pfSolver;
122#if defined(WITH_KLU) || defined(WITH_SPARSE)
124 pfSolver = std::make_shared<PFSolverPowerPolarSparse>(
127 pfSolver = std::make_shared<PFSolverPowerPolar>(**
mName,
mSystem,
131 pfSolver = std::make_shared<PFSolverPowerPolar>(**
mName,
mSystem,
146 solver->initialize();
159 for (
auto comp :
mSystem.mComponents) {
160 auto odeComp = std::dynamic_pointer_cast<ODEInterface>(comp);
163 auto odeSolver = std::make_shared<ODESolver>(
164 odeComp->mAttributeList->attributeTyped<
String>(
"name")->get() +
175 std::vector<SystemTopology> subnets;
179 mSystem.splitSubnets<VarType>(subnets);
183 for (
UInt net = 0; net < subnets.size(); ++net) {
185 if (subnets.size() > 1)
186 copySuffix =
"_" + std::to_string(net);
192 throw std::logic_error(
"MNA state-space extraction does not support "
193 "Diakoptics/tearing.");
196 solver = std::make_shared<DiakopticsSolver<VarType>>(
213 solver->setSystem(subnets[net]);
217 solver->setDirectLinearSolverConfiguration(
219 solver->initialize();
227 SPDLOG_LOGGER_INFO(
mLog,
"Start synchronization with remotes on interfaces");
235 SPDLOG_LOGGER_INFO(
mLog,
"Synchronized simulation start with remotes");
243 for (
auto t : solver->getTasks()) {
249 for (
auto t : intf->getTasks()) {
255 mTasks.push_back(logger->getTask());
258 mScheduler = std::make_shared<SequentialScheduler>();
264 SPDLOG_LOGGER_INFO(
mLog,
"Scheduling tasks.");
267 SPDLOG_LOGGER_INFO(
mLog,
"Scheduling done.");
275 std::map<CPS::Task::Ptr, Scheduler::TaskTime> avgTimes;
276 std::map<CPS::Task::Ptr, String> fillColors;
283 static std::map<std::type_index, String> colorMap;
284 auto tid = std::type_index(
typeid(task.get()));
286 if (colorMap.find(tid) != colorMap.end()) {
288 String(
"/paired9/") + std::to_string(1 + colorMap.size() % 9);
291 return colorMap[tid];
294 auto avgTimeWorst = Scheduler::TaskTime::min();
295 for (
auto task :
mTasks) {
296 avgTimes[task] =
mScheduler->getAveragedMeasurement(task);
298 if (avgTimes[task] > avgTimeWorst)
299 avgTimeWorst = avgTimes[task];
306 Graph::Graph g(
"dependencies", Graph::Type::directed);
307 for (
auto task :
mTasks) {
311 auto *n = g.addNode(
name);
313 std::stringstream label;
316 label <<
"<FONT POINT-SIZE=\"10\" COLOR=\"gray28\">"
319 if (isScheduled(task))
320 label <<
"Avg. time: " << avgTimes[task].count() <<
"ns<BR/>";
322 label <<
"Unscheduled"
327 n->set(
"color", getColor(task));
328 n->set(
"label", label.str(),
true);
329 n->set(
"style",
"rounded,filled,bold");
330 n->set(
"shape",
"rectangle");
332 if (isScheduled(task)) {
334 auto grad = (float)avgTimes[task].count() / avgTimeWorst.count();
336 SPDLOG_LOGGER_INFO(
mLog,
"{} {}", task->toString(),
340 n->set(
"fillcolor",
"white");
343 for (
auto from :
mTasks) {
345 g.addEdge(
"", g.node(from->toString()), g.node(to->toString()));
349 g.set(
"splines",
"ortho");
405 SPDLOG_LOGGER_INFO(
mLog,
"Initialize simulation: {}", **
mName);
412 SPDLOG_LOGGER_INFO(
mLog,
"Opening interfaces.");
419 SPDLOG_LOGGER_INFO(
mLog,
"Start simulation: {}", **
mName);
441 SPDLOG_LOGGER_INFO(
mLog,
"Simulation calculation time: {:.6f}",
452 SPDLOG_LOGGER_INFO(
mLog,
"Simulation finished.");
476 std::chrono::steady_clock::time_point
start;
478 start = std::chrono::steady_clock::now();
488 auto end = std::chrono::steady_clock::now();
489 std::chrono::duration<double> diff = end -
start;
496 auto stepTimeLog =
Logger::get(logName, Logger::Level::info);
498 SPDLOG_LOGGER_WARN(
mLog,
"Collection of step times has been disabled.");
502 SPDLOG_LOGGER_INFO(stepTimeLog,
"step_time");
504 Real stepTimeSum = 0;
507 SPDLOG_LOGGER_INFO(stepTimeLog,
"{:.9f}", meas);
509 SPDLOG_LOGGER_INFO(
mLog,
"Average step time: {:.9f}",
514 auto stepTimeLog =
Logger::get(logName, Logger::Level::info);
516 SPDLOG_LOGGER_INFO(stepTimeLog,
"overruns");
522 SPDLOG_LOGGER_INFO(
mLog,
"overrun detected {}: {:.9f}", overruns, meas);
525 SPDLOG_LOGGER_INFO(
mLog,
"Detected {} overruns.", overruns);
530 solver->logLUTimes();
536 if (solverIndex >=
mSolvers.size()) {
537 throw std::out_of_range(
538 "Simulation::getStateSpaceExtractor(): solver index out of range.");
541 if (
const auto realMnaSolver =
543 return realMnaSolver->getStateSpaceExtractor();
546 if (
const auto complexMnaSolver =
549 return complexMnaSolver->getStateSpaceExtractor();
552 throw std::logic_error(
553 "Simulation::getStateSpaceExtractor(): selected solver is not an "
570 mLog,
"Attribute with name {} not found on component {}", attr, comp);
574 SPDLOG_LOGGER_ERROR(
mLog,
"Component or node with name {} not found", comp);
589 throw SystemError(
"Cannot log attributes when no logger is configured for "
AttributePointer< AttributeBase > Ptr
std::shared_ptr< IdentifiedObject > Ptr
spdlog::level::level_enum Level
static void setLogPattern(std::shared_ptr< spdlog::logger > logger, std::string pattern)
static Log get(const std::string &name, Level filelevel=Level::info, Level clilevel=Level::off)
std::shared_ptr< Task > Ptr
static std::shared_ptr< MnaSolver< VarType > > factory(String name, CPS::Domain domain=CPS::Domain::DP, CPS::Logger::Level logLevel=CPS::Logger::Level::info, DirectLinearSolverImpl implementation=mSupportedSolverImpls().back(), String pluginName="plugin.so")
sovlerImpl: choose the most advanced solver implementation available by default
Solver class using Modified Nodal Analysis (MNA).
std::chrono::steady_clock::duration TaskTime
Time measurement for the task execution.
void logIdObjAttribute(const String &comp, const String &attr)
Bool mStateSpaceExtraction
Enable extraction of the MNA-coupled discrete-time state matrix.
CPS::UInt getPFMaxIterations() const
std::chrono::duration< double > mSimulationCalculationTime
Measured calculation time for simulation.
void logLUTimes()
Write LU decomposition times measurements to log file.
void sync() const
Synchronize simulation with remotes by exchanging intial state over interfaces.
CPS::IdentifiedObject::List mTearComponents
CPS::Logger::Level mLogLevel
Simulation log level.
void setPFSolverBaseVoltageLooseTolerance(Real tolerance)
DirectLinearSolverConfiguration mDirectLinearSolverConfiguration
Bool mInitFromNodesAndTerminals
virtual Real step()
Solve system A * x = z for x and current time.
Scheduler::Edges mTaskInEdges
Task dependencies as incoming / outgoing edges.
const CPS::Attribute< Real >::Ptr mTimeStep
Simulation timestep.
const CPS::Attribute< CPS::UInt >::Ptr mPFMaxIterations
Maximum number of Newton-Raphson iterations for the PF solver.
void setPFKeepLastSolution(Bool value)
const CPS::Attribute< Bool >::Ptr mSteadyStateInit
const CPS::Attribute< Real >::Ptr mPFBaseVoltageStrictTolerance
Strict tolerance between authoritative base-voltage sources in a zone; default 0.01.
Real next()
Run until next time step.
void logStepTimes(String logName)
Write step time measurements to log file.
Bool getPFSolverEnforceReactiveLimits() const
String mSolverPluginName
If there we use a solver plugin, this specifies its name (excluding .so)
void initialize()
Create solver instances etc.
const CPS::Attribute< Bool >::Ptr mPFKeepLastSolution
void setPFMaxIterations(CPS::UInt value)
void setPFBaseApparentPowerFallback(Real value)
Bool getPFSolverUseSparse() const
std::vector< Real > mStepTimes
(Real) time needed for the timesteps
const CPS::Attribute< Real >::Ptr mFinalTime
Final time of the simulation.
void prepSchedule()
Prepare schedule for simulation.
Int mTimeStepCount
Number of step which have been executed for this simulation.
const CPS::Attribute< Real >::Ptr mPFBaseApparentPowerFallback
Real mSteadStIniTimeLimit
steady state initialization time limit
Solver::SystemMatrixRecomputationMode mSystemMatrixRecomputationMode
Requested system-matrix recomputation mode.
Solver::Behaviour mSolverBehaviour
Real getPFBaseApparentPowerFallback() const
DirectLinearSolverImpl mDirectImpl
CPS::Task::List mTasks
List of all tasks to be scheduled.
const CPS::Attribute< Bool >::Ptr mSplitSubnets
std::shared_ptr< Scheduler > mScheduler
Scheduler used for task scheduling.
Bool getPFKeepLastSolution() const
std::vector< Interface::Ptr > mInterfaces
Vector of Interfaces.
void setPFSolverUseSparse(Bool value)
Bool mLogStepTimes
activate collection of step times
void create()
Helper function for constructors.
void setPFSolverEnforceReactiveLimits(Bool value)
CPS::SystemTopology mSystem
System list.
void checkForOverruns(String logName)
Check for overruns.
Real getPFSolverBaseVoltageLooseTolerance() const
Simulation(String name, CommandLineArgs &args)
Creates simulation with name and CommandLineArgs.
const CPS::Attribute< Bool >::Ptr mPFEnforceReactiveLimits
CPS::AttributeBase::Ptr getIdObjAttribute(const String &comp, const String &attr)
CHECK: Can these be deleted? getIdObjAttribute + "**attr =" should suffice.
void start()
Start simulation without advancing in time.
EventQueue mEvents
The simulation event queue.
void schedule()
Create the schedule for the independent tasks.
const CPS::Attribute< Bool >::Ptr mPFSolverUseSparse
std::chrono::time_point< std::chrono::steady_clock > mSimulationStartTimePoint
Start time point to measure calculation time.
Scheduler::Edges mTaskOutEdges
Real mTime
Time variable that is incremented at every step.
Real mSteadStIniAccLimit
steady state initialization accuracy limit
const CPS::Attribute< Real >::Ptr mPFBaseVoltageLooseTolerance
Loose tolerance for a zone's Load base-voltage vs. its rating; default 0.1.
void createMNASolver()
Subroutine for MNA only because there are many MNA options.
void run()
Run simulation until total time is elapsed.
void setPFSolverBaseVoltageStrictTolerance(Real tolerance)
void logAttribute(String name, CPS::AttributeBase::Ptr attr)
CHECK: Can we store the attribute name / UID intrinsically inside the attribute?
DataLoggerInterface::List mLoggers
The data loggers.
const MNAStateSpaceExtractor & getStateSpaceExtractor(UInt solverIndex=0) const
void createSolvers()
Create solvers depending on simulation settings.
const CPS::Attribute< String >::Ptr mName
Simulation name.
Real getPFSolverBaseVoltageStrictTolerance() const
CPS::Logger::Log mLog
Simulation logger.
void stop()
Stop simulation including scheduler and interfaces.
std::chrono::time_point< std::chrono::steady_clock > mSimulationEndTimePoint
End time point to measure calculation time.
std::shared_ptr< Solver > Ptr
static std::shared_ptr< AttributeList > make(Args &&...args)
String className(T *ptr, const String &prefix="CPS::")
String encodeXml(String &data)
static Rgb gradient(double x)