8 #include <dpsim-models/Utils.h>
9 #include <dpsim/DiakopticsSolver.h>
10 #include <dpsim/MNASolverFactory.h>
11 #include <dpsim/PFSolverPowerPolar.h>
12 #include <dpsim/SequentialScheduler.h>
13 #include <dpsim/Simulation.h>
14 #include <dpsim/Utils.h>
16 #include <spdlog/sinks/stdout_color_sinks.h>
19 #include <dpsim-models/CIM/Reader.h>
23 #include <dpsim-models/Solver/ODEInterface.h>
24 #include <dpsim/DAESolver.h>
25 #include <dpsim/ODESolver.h>
29 using namespace DPsim;
31 Simulation::Simulation(String name, Logger::Level logLevel)
43 mSolverPluginName(args.solverPluginName),
48 mLogLevel(args.logLevel), mDomain(args.solver.domain),
49 mSolverType(args.solver.type), mDirectImpl(args.directImpl) {
58 Eigen::setNbThreads(1);
73 createSolvers<Complex>();
76 createSolvers<Real>();
90 switch (mSolverType) {
91 case Solver::Type::MNA:
92 createMNASolver<VarType>();
95 case Solver::Type::DAE:
97 mSolvers.push_back(solver);
100 case Solver::Type::NRP:
103 solver->doInitFromNodesAndTerminals(mInitFromNodesAndTerminals);
104 solver->setSolverAndComponentBehaviour(mSolverBehaviour);
105 solver->initialize();
106 mSolvers.push_back(solver);
116 auto odeComp = std::dynamic_pointer_cast<ODEInterface>(comp);
119 auto odeSolver = std::make_shared<ODESolver>(
120 odeComp->mAttributeList->attributeTyped<String>(
"name")->get() +
123 mSolvers.push_back(odeSolver);
131 std::vector<SystemTopology> subnets;
135 mSystem.splitSubnets<VarType>(subnets);
139 for (UInt net = 0; net < subnets.size(); ++net) {
141 if (subnets.size() > 1)
142 copySuffix =
"_" + std::to_string(net);
148 solver = std::make_shared<DiakopticsSolver<VarType>>(
152 solver = MnaSolverFactory::factory<VarType>(**
mName + copySuffix, mDomain,
160 solver->setSystem(subnets[net]);
161 solver->setSolverAndComponentBehaviour(mSolverBehaviour);
162 solver->doInitFromNodesAndTerminals(mInitFromNodesAndTerminals);
164 solver->setDirectLinearSolverConfiguration(
165 mDirectLinearSolverConfiguration);
166 solver->initialize();
169 mSolvers.push_back(solver);
174 SPDLOG_LOGGER_INFO(
mLog,
"Start synchronization with remotes on interfaces");
182 SPDLOG_LOGGER_INFO(
mLog,
"Synchronized simulation start with remotes");
187 mTaskOutEdges.clear();
189 for (
auto solver : mSolvers) {
190 for (
auto t : solver->getTasks()) {
196 for (
auto t : intf->getTasks()) {
202 mTasks.push_back(logger->getTask());
205 mScheduler = std::make_shared<SequentialScheduler>();
211 SPDLOG_LOGGER_INFO(
mLog,
"Scheduling tasks.");
214 SPDLOG_LOGGER_INFO(
mLog,
"Scheduling done.");
222 std::map<CPS::Task::Ptr, Scheduler::TaskTime> avgTimes;
223 std::map<CPS::Task::Ptr, String> fillColors;
255 auto isScheduled = [
this](Task::Ptr task) -> Bool {
256 return !mTaskOutEdges[task].empty();
259 auto getColor = [](Task::Ptr task) -> String {
260 static std::map<std::type_index, String> colorMap;
261 auto tid = std::type_index(
typeid(task.get()));
263 if (colorMap.find(tid) != colorMap.end()) {
265 String(
"/paired9/") + std::to_string(1 + colorMap.size() % 9);
268 return colorMap[tid];
271 auto avgTimeWorst = Scheduler::TaskTime::min();
272 for (
auto task :
mTasks) {
273 avgTimes[task] =
mScheduler->getAveragedMeasurement(task);
275 if (avgTimes[task] > avgTimeWorst)
276 avgTimeWorst = avgTimes[task];
284 for (
auto task :
mTasks) {
285 String name = task->toString();
286 String type = CPS::Utils::className(task.get(),
"DPsim::");
288 auto *n = g.addNode(name);
290 std::stringstream label;
292 label <<
"<B>" << Utils::encodeXml(name) <<
"</B><BR/>";
293 label <<
"<FONT POINT-SIZE=\"10\" COLOR=\"gray28\">"
294 << Utils::encodeXml(type) <<
"<BR/>";
296 if (isScheduled(task))
297 label <<
"Avg. time: " << avgTimes[task].count() <<
"ns<BR/>";
299 label <<
"Unscheduled"
304 n->set(
"color", getColor(task));
305 n->set(
"label", label.str(),
true);
306 n->set(
"style",
"rounded,filled,bold");
307 n->set(
"shape",
"rectangle");
315 if (isScheduled(task)) {
317 auto grad = (float)avgTimes[task].count() / avgTimeWorst.count();
318 n->set(
"fillcolor", CPS::Utils::Rgb::gradient(grad).hex());
319 SPDLOG_LOGGER_INFO(
mLog,
"{} {}", task->toString(),
320 CPS::Utils::Rgb::gradient(grad).hex());
323 n->set(
"fillcolor",
"white");
326 for (
auto from :
mTasks) {
327 for (
auto to : mTaskOutEdges[from]) {
328 g.addEdge(
"", g.node(from->toString()), g.node(to->toString()));
332 g.set(
"splines",
"ortho");
338 SPDLOG_LOGGER_INFO(
mLog,
"Initialize simulation: {}", **
mName);
342 SPDLOG_LOGGER_INFO(
mLog,
"Opening interfaces.");
349 SPDLOG_LOGGER_INFO(
mLog,
"Start simulation: {}", **
mName);
355 if (mSolverType != Solver::Type::NRP) {
371 SPDLOG_LOGGER_INFO(
mLog,
"Simulation calculation time: {:.6f}",
382 SPDLOG_LOGGER_INFO(
mLog,
"Simulation finished.");
406 auto start = std::chrono::steady_clock::now();
414 auto end = std::chrono::steady_clock::now();
415 std::chrono::duration<double> diff = end -
start;
421 auto stepTimeLog = Logger::get(logName, Logger::Level::info);
422 Logger::setLogPattern(stepTimeLog,
"%v");
423 stepTimeLog->info(
"step_time");
425 Real stepTimeSum = 0;
428 stepTimeLog->info(
"{:.9f}", meas);
430 SPDLOG_LOGGER_INFO(
mLog,
"Average step time: {:.9f}",
435 for (
auto solver : mSolvers) {
436 solver->logLUTimes();
441 const String &attr) {
453 mLog,
"Attribute with name {} not found on component {}", attr, comp);
457 SPDLOG_LOGGER_ERROR(
mLog,
"Component or node with name {} not found", comp);
462 void Simulation::logIdObjAttribute(
const String &comp,
const String &attr) {
464 String name = comp +
"." + attr;
470 mLoggers[0]->logAttribute(name, attr);
472 throw SystemError(
"Cannot log attributes when no logger is configured for "
IdentifiedObject::List mComponents
List of network components.
std::shared_ptr< Type > node(UInt index)
Returns TopologicalNode by index in node list.
std::shared_ptr< Type > component(const String &name)
Returns Component by name.
std::chrono::steady_clock::duration TaskTime
Time measurement for the task execution.
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.
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.
DataLogger::List mLoggers
The data loggers.
const CPS::Attribute< Bool >::Ptr mSteadyStateInit
Real next()
Run until next time step.
void logStepTimes(String logName)
Write step time measurements to log file.
String mSolverPluginName
If there we use a solver plugin, this specifies its name (excluding .so)
void initialize()
Create solver instances etc.
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.
Real mSteadStIniTimeLimit
steady state initialization time limit
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.
std::vector< Interface::Ptr > mInterfaces
Vector of Interfaces.
void create()
Helper function for constructors.
CPS::SystemTopology mSystem
System list.
Simulation(String name, CommandLineArgs &args)
Creates simulation with name and CommandLineArgs.
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.
std::chrono::time_point< std::chrono::steady_clock > mSimulationStartTimePoint
Start time point to measure calculation time.
Real mTime
Time variable that is incremented at every step.
Bool mSystemMatrixRecomputation
Enable recomputation of system matrix during simulation.
Real mSteadStIniAccLimit
steady state initialization accuracy limit
void createMNASolver()
Subroutine for MNA only because there are many MNA options.
void run()
Run simulation until total time is elapsed.
void logAttribute(String name, CPS::AttributeBase::Ptr attr)
CHECK: Can we store the attribute name / UID intrinsically inside the attribute?
void createSolvers()
Create solvers depending on simulation settings.
const CPS::Attribute< String >::Ptr mName
Simulation name.
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.