DPsim
Loading...
Searching...
No Matches
Attribute.h
Go to the documentation of this file.
1/* Copyright 2017-2022 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#pragma once
10#include <iostream>
11#include <set>
12
13#include <dpsim-models/Config.h>
17namespace CPS {
18
33
34template <class T> class Attribute;
35
36template <class T> class AttributeStatic;
37
38template <class T> class AttributeDynamic;
39
46template <class T> class AttributePointer {
47public:
48 using element_type = T;
49
50 AttributePointer() : mPtr(){};
52 AttributePointer(std::shared_ptr<T> ptr) : mPtr(ptr){};
53 AttributePointer(std::nullptr_t ptr) : mPtr(ptr){};
54 explicit AttributePointer(T *ptr) : mPtr(ptr){};
55
56 template <class U> AttributePointer(AttributePointer<U> ptr) : mPtr() {
57 this->mPtr = ptr.getPtr();
58 };
59
60 template <class U> AttributePointer(std::shared_ptr<U> ptr) : mPtr(ptr){};
61
63 this->mPtr = r.getPtr();
64 return *this;
65 };
66
67 template <class U>
69 this->mPtr = r.getPtr();
70 return *this;
71 };
72
74 this->mPtr = r.getPtr();
75 return *this;
76 }
77
79 this->mPtr = r.getPtr();
80 return *this;
81 }
82
83 T &operator*() const noexcept { return *mPtr; }
84
85 T *operator->() const noexcept { return mPtr.operator->(); }
86
87 T *get() const { return mPtr.get(); }
88
89 std::shared_ptr<T> getPtr() const { return mPtr; }
90
91 bool isNull() const { return mPtr == nullptr; }
92
93private:
94 std::shared_ptr<T> mPtr;
95};
96
100template <class T> struct AttributeCmp {
102 CPS::AttributePointer<T> b) const {
103 return a.getPtr() < b.getPtr();
104 }
105};
106
110template <class T> struct AttributeEq {
112 CPS::AttributePointer<T> b) const {
113 return a.getPtr() == b.getPtr();
114 }
115};
116
121public:
123 typedef std::vector<Ptr> List;
124 typedef std::set<Ptr, AttributeCmp<AttributeBase>> Set;
125 typedef std::map<String, Ptr> Map;
126
130 virtual String toString() = 0;
131
136 virtual bool isStatic() const = 0;
137
138 virtual ~AttributeBase() = default;
139
144 virtual bool copyValue(AttributeBase::Ptr copyFrom) = 0;
145
150 virtual const std::type_info &getType() = 0;
151
157
163 virtual void appendDependencies(AttributeBase::Set *deps) = 0;
164
171 this->appendDependencies(&deps);
172 return deps;
173 }
174};
175
179template <class DependentType> class AttributeUpdateTaskBase {
180
181public:
182 typedef std::shared_ptr<AttributeUpdateTaskBase<DependentType>> Ptr;
183
184 virtual void executeUpdate(std::shared_ptr<DependentType> &dependent) = 0;
186 virtual ~AttributeUpdateTaskBase() = default;
187};
188
194template <class DependentType, class... DependencyTypes>
196 : public AttributeUpdateTaskBase<DependentType>,
197 public SharedFactory<
198 AttributeUpdateTask<DependentType, DependencyTypes...>> {
199
200public:
201 using Actor =
202 std::function<void(std::shared_ptr<DependentType> &,
204
205protected:
206 std::tuple<typename Attribute<DependencyTypes>::Ptr...> mDependencies;
209
210public:
212 typename Attribute<DependencyTypes>::Ptr... dependencies)
213 : mDependencies(std::move(dependencies)...),
214 mActorFunction(actorFunction), mKind(kind) {}
215
216 virtual void
217 executeUpdate(std::shared_ptr<DependentType> &dependent) override {
219 dependent,
220 std::get<typename Attribute<DependencyTypes>::Ptr...>(mDependencies));
221 }
222
227 return std::apply(
228 [](auto &&...elems) {
229 return std::vector<AttributeBase::Ptr>{
230 std::forward<decltype(elems)>(elems)...};
231 },
233 };
234};
235
240template <class T>
242 public std::enable_shared_from_this<Attribute<T>> {
243
244protected:
245 std::shared_ptr<T> mData;
246
247public:
248 using Type = T;
250
251 Attribute(T initialValue = T())
252 : AttributeBase(), mData(std::make_shared<T>()) {
253 *mData = initialValue;
254 }
255
260 virtual void set(T value) = 0;
261
265 virtual T &get() = 0;
266
273 virtual void setReference(Attribute<T>::Ptr reference) = 0;
274
279 virtual std::shared_ptr<T> asRawPointer() = 0;
280
284 String toString() override {
285 std::stringstream ss;
286 ss << this->get();
287 return ss.str();
288 }
289
300 operator const T &() { return this->get(); }
301
307 T &operator*() { return this->get(); }
308
313 bool copyValue(AttributeBase::Ptr copyFrom) override {
314 Attribute<T>::Ptr copyFromTyped =
315 std::dynamic_pointer_cast<Attribute<T>>(copyFrom.getPtr());
316 if (copyFromTyped.getPtr() == nullptr) {
317 return false;
318 }
319 this->set(**copyFromTyped);
320 return true;
321 }
322
327 const std::type_info &getType() override { return typeid(T); }
328
336 // TODO: This is in the real time path. We should not use heap here.
337 };
338
347 template <class U>
348 typename Attribute<U>::Ptr
351 typename AttributeUpdateTask<U, T>::Actor setter =
353 auto derivedAttribute = std::make_shared<AttributeDynamic<U>>();
354 if (setter) {
355 derivedAttribute->addTask(
359 Attribute<T>::Ptr(this->shared_from_this())));
360 }
361 if (getter) {
362 derivedAttribute->addTask(
366 Attribute<T>::Ptr(this->shared_from_this())));
367 }
368 return derivedAttribute;
369 }
370
375 template <typename U = T,
376 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
378 // requires std::same_as<T, CPS::Complex> //CPP20
379 {
381 [](std::shared_ptr<Real> &dependent,
382 typename Attribute<Complex>::Ptr dependency) {
383 *dependent = (**dependency).real();
384 };
386 [](std::shared_ptr<Real> &dependent,
387 typename Attribute<Complex>::Ptr dependency) {
388 CPS::Complex currentValue = dependency->get();
389 currentValue.real(*dependent);
390 dependency->set(currentValue);
391 };
392 return derive<CPS::Real>(getter, setter);
393 }
394
399 template <typename U = T,
400 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
402 // requires std::same_as<T, CPS::Complex> //CPP20
403 {
405 [](std::shared_ptr<Real> &dependent,
406 Attribute<Complex>::Ptr dependency) {
407 *dependent = (**dependency).imag();
408 };
410 [](std::shared_ptr<Real> &dependent,
411 Attribute<Complex>::Ptr dependency) {
412 CPS::Complex currentValue = dependency->get();
413 currentValue.imag(*dependent);
414 dependency->set(currentValue);
415 };
416 return derive<CPS::Real>(getter, setter);
417 }
418
423 template <typename U = T,
424 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
426 // requires std::same_as<T, CPS::Complex> //CPP20
427 {
429 [](std::shared_ptr<Real> &dependent,
430 Attribute<Complex>::Ptr dependency) {
431 *dependent = Math::abs(**dependency);
432 };
434 [](std::shared_ptr<Real> &dependent,
435 Attribute<Complex>::Ptr dependency) {
436 CPS::Complex currentValue = dependency->get();
437 dependency->set(Math::polar(*dependent, Math::phase(currentValue)));
438 };
439 return derive<CPS::Real>(getter, setter);
440 }
441
446 template <typename U = T,
447 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
449 // requires std::same_as<T, CPS::Complex> //CPP20
450 {
452 [](std::shared_ptr<Real> &dependent,
453 Attribute<Complex>::Ptr dependency) {
454 *dependent = Math::phase(**dependency);
455 };
457 [](std::shared_ptr<Real> &dependent,
458 Attribute<Complex>::Ptr dependency) {
459 CPS::Complex currentValue = dependency->get();
460 dependency->set(Math::polar(Math::abs(currentValue), *dependent));
461 };
462 return derive<CPS::Real>(getter, setter);
463 }
464
470 template <typename U = T, std::enable_if_t<std::is_same_v<Real, U> ||
471 std::is_same_v<Complex, U>,
472 bool> = true>
474 // requires std::same_as<T, CPS::Complex> || std::same_as<T, CPS::Real> //CPP20
475 {
476 typename AttributeUpdateTask<T, T>::Actor getter =
477 [scale](std::shared_ptr<T> &dependent, Attribute<T>::Ptr dependency) {
478 *dependent = scale * (**dependency);
479 };
480 typename AttributeUpdateTask<T, T>::Actor setter =
481 [scale](std::shared_ptr<T> &dependent, Attribute<T>::Ptr dependency) {
482 dependency->set((*dependent) / scale);
483 };
484 return derive<T>(getter, setter);
485 }
486
494 template <class U, class V = T,
495 std::enable_if_t<std::is_same_v<CPS::MatrixVar<U>, V>, bool> = true>
498 typename CPS::MatrixVar<U>::Index column)
499 // requires std::same_as<T, CPS::MatrixVar<U>> //CPP20
500 {
501 typename AttributeUpdateTask<U, T>::Actor getter =
502 [row, column](std::shared_ptr<U> &dependent,
503 Attribute<T>::Ptr dependency) {
504 *dependent = (**dependency)(row, column);
505 };
506 typename AttributeUpdateTask<U, T>::Actor setter =
507 [row, column](std::shared_ptr<U> &dependent,
508 Attribute<T>::Ptr dependency) {
509 CPS::MatrixVar<U> currentValue = dependency->get();
510 currentValue(row, column) = *dependent;
511 dependency->set(currentValue);
512 };
513 return derive<U>(getter, setter);
514 }
515};
516
521template <class T>
522class AttributeStatic : public Attribute<T>,
523 public SharedFactory<AttributeStatic<T>> {
524 friend class SharedFactory<AttributeStatic<T>>;
525
526public:
527 AttributeStatic(T initialValue = T()) : Attribute<T>(initialValue) {}
528
529 virtual void set(T value) override { *this->mData = value; };
530
531 virtual T &get() override { return *this->mData; };
532
533 virtual bool isStatic() const override { return true; }
534
535 virtual void setReference(typename Attribute<T>::Ptr reference) override {
536 throw TypeException();
537 }
538
539 virtual std::shared_ptr<T> asRawPointer() override { return this->mData; }
540
541 virtual void appendDependencies(AttributeBase::Set *deps) override {
542 deps->insert(this->shared_from_this());
543 }
544};
545
549template <class T>
550class AttributeDynamic : public Attribute<T>,
551 public SharedFactory<AttributeDynamic<T>> {
552 friend class SharedFactory<AttributeDynamic<T>>;
553
554protected:
555 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnce;
556 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnGet;
557 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnSet;
558
559public:
560 AttributeDynamic(T initialValue = T()) : Attribute<T>(initialValue) {}
561
568 typename AttributeUpdateTaskBase<T>::Ptr task) {
569 switch (kind) {
571 updateTasksOnce.push_back(task);
572 // THISISBAD: This is probably not the right time to run this kind of task
573 task->executeUpdate(this->mData);
574 break;
576 updateTasksOnGet.push_back(task);
577 break;
579 updateTasksOnSet.push_back(task);
580 break;
583 };
584 }
585
591 switch (kind) {
593 updateTasksOnce.clear();
594 break;
596 updateTasksOnGet.clear();
597 break;
599 updateTasksOnSet.clear();
600 break;
603 };
604 }
605
610 updateTasksOnce.clear();
611 updateTasksOnGet.clear();
612 updateTasksOnSet.clear();
613 }
614
615 virtual void setReference(typename Attribute<T>::Ptr reference) override {
616 typename AttributeUpdateTask<T, T>::Actor getter =
617 [](std::shared_ptr<T> &dependent,
618 typename Attribute<T>::Ptr dependency) {
619 dependent = dependency->asRawPointer();
620 };
621 this->clearAllTasks();
622 if (reference->isStatic()) {
625 getter, reference));
626 } else {
629 UpdateTaskKind::UPDATE_ON_GET, getter, reference));
630 }
631 }
632
633 virtual std::shared_ptr<T> asRawPointer() override {
635 task->executeUpdate(this->mData);
636 }
637 return this->mData;
638 }
639
640 virtual void set(T value) override {
641 *this->mData = value;
643 task->executeUpdate(this->mData);
644 }
645 };
646
647 virtual T &get() override {
649 task->executeUpdate(this->mData);
650 }
651 return *this->mData;
652 };
653
654 virtual bool isStatic() const override { return false; }
655
661 virtual void appendDependencies(AttributeBase::Set *deps) override {
662 deps->insert(this->shared_from_this());
663
666 AttributeBase::List taskDeps = task->getDependencies();
667 newDeps.insert(taskDeps.begin(), taskDeps.end());
668 }
669
671 AttributeBase::List taskDeps = task->getDependencies();
672 newDeps.insert(taskDeps.begin(), taskDeps.end());
673 }
674
675 for (auto dependency : newDeps) {
676 dependency->appendDependencies(deps);
677 }
678 }
679};
680
682
684
686
687} // namespace CPS
688
689namespace std {
693template <typename T> struct hash<CPS::AttributePointer<T>> {
694 size_t operator()(CPS::AttributePointer<T> const &x) const {
695 return std::hash<std::shared_ptr<T>>()(x.getPtr());
696 }
697};
698} // namespace std
virtual bool isStatic() const =0
virtual const std::type_info & getType()=0
Get the type of this attribute.
virtual ~AttributeBase()=default
virtual bool copyValue(AttributeBase::Ptr copyFrom)=0
Copy the attribute value of copyFrom onto this attribute.
virtual String toString()=0
virtual AttributeBase::Set getDependencies() final
Definition Attribute.h:169
virtual void appendDependencies(AttributeBase::Set *deps)=0
virtual AttributeBase::Ptr cloneValueOntoNewAttribute()=0
Generates a new attribute of the same type and copies the current value in the heap....
AttributePointer< AttributeBase > Ptr
Definition Attribute.h:122
std::vector< Ptr > List
Definition Attribute.h:123
std::set< Ptr, AttributeCmp< AttributeBase > > Set
Definition Attribute.h:124
std::map< String, Ptr > Map
Definition Attribute.h:125
AttributeDynamic(T initialValue=T())
Definition Attribute.h:560
void addTask(UpdateTaskKind kind, typename AttributeUpdateTaskBase< T >::Ptr task)
Definition Attribute.h:567
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnGet
Definition Attribute.h:556
virtual void setReference(typename Attribute< T >::Ptr reference) override
Definition Attribute.h:615
virtual void appendDependencies(AttributeBase::Set *deps) override
Definition Attribute.h:661
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnSet
Definition Attribute.h:557
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnce
Definition Attribute.h:555
void clearTasks(UpdateTaskKind kind)
Definition Attribute.h:590
virtual void set(T value) override
Definition Attribute.h:640
virtual std::shared_ptr< T > asRawPointer() override
Definition Attribute.h:633
virtual bool isStatic() const override
Definition Attribute.h:654
virtual T & get() override
Definition Attribute.h:647
const std::type_info & getType() override
Get the type of this attribute.
Definition Attribute.h:327
T & operator*()
User-defined dereference operator.
Definition Attribute.h:307
AttributePointer< Attribute< T > > deriveScaled(T scale)
Definition Attribute.h:473
Attribute(T initialValue=T())
Definition Attribute.h:251
AttributePointer< Attribute< Real > > deriveImag()
Definition Attribute.h:401
AttributePointer< Attribute< Real > > derivePhase()
Definition Attribute.h:448
AttributePointer< Attribute< U > > deriveCoeff(typename CPS::MatrixVar< U >::Index row, typename CPS::MatrixVar< U >::Index column)
Definition Attribute.h:497
virtual std::shared_ptr< T > asRawPointer()=0
AttributePointer< Attribute< Real > > deriveReal()
Definition Attribute.h:377
virtual void setReference(Attribute< T >::Ptr reference)=0
virtual void set(T value)=0
String toString() override
Fallback method for all attribute types not covered by the specifications in Attribute....
Definition Attribute.h:284
AttributeBase::Ptr cloneValueOntoNewAttribute() override
Generates a new attribute of the same type and copies the current value in the heap....
Definition Attribute.h:333
virtual T & get()=0
AttributePointer< Attribute< Real > > deriveMag()
Definition Attribute.h:425
bool copyValue(AttributeBase::Ptr copyFrom) override
Copy the attribute value of copyFrom onto this attribute.
Definition Attribute.h:313
std::shared_ptr< T > mData
Definition Attribute.h:245
AttributePointer< Attribute< T > > Ptr
Definition Attribute.h:249
Attribute< U >::Ptr derive(typename AttributeUpdateTask< U, T >::Actor getter=typename AttributeUpdateTask< U, T >::Actor(), typename AttributeUpdateTask< U, T >::Actor setter=typename AttributeUpdateTask< U, T >::Actor())
Definition Attribute.h:349
AttributePointer(std::nullptr_t ptr)
Definition Attribute.h:53
AttributePointer(std::shared_ptr< T > ptr)
Definition Attribute.h:52
AttributePointer & operator=(const AttributePointer< U > &r) noexcept
Definition Attribute.h:68
T & operator*() const noexcept
Definition Attribute.h:83
AttributePointer(std::shared_ptr< U > ptr)
Definition Attribute.h:60
AttributePointer & operator=(AttributePointer< U > &&r)
Definition Attribute.h:78
T * operator->() const noexcept
Definition Attribute.h:85
AttributePointer & operator=(AttributePointer &&r)
Definition Attribute.h:73
std::shared_ptr< T > getPtr() const
Definition Attribute.h:89
bool isNull() const
Definition Attribute.h:91
AttributePointer(const AttributePointer &r)=default
AttributePointer(AttributePointer< U > ptr)
Definition Attribute.h:56
AttributePointer & operator=(const AttributePointer &r) noexcept
Definition Attribute.h:62
virtual void set(T value) override
Definition Attribute.h:529
virtual std::shared_ptr< T > asRawPointer() override
Definition Attribute.h:539
virtual void appendDependencies(AttributeBase::Set *deps) override
Definition Attribute.h:541
AttributeStatic(T initialValue=T())
Definition Attribute.h:527
virtual void setReference(typename Attribute< T >::Ptr reference) override
Definition Attribute.h:535
virtual bool isStatic() const override
Definition Attribute.h:533
virtual T & get() override
Definition Attribute.h:531
virtual ~AttributeUpdateTaskBase()=default
virtual AttributeBase::List getDependencies()=0
virtual void executeUpdate(std::shared_ptr< DependentType > &dependent)=0
std::shared_ptr< AttributeUpdateTaskBase< DependentType > > Ptr
Definition Attribute.h:182
virtual void executeUpdate(std::shared_ptr< DependentType > &dependent) override
Definition Attribute.h:217
AttributeUpdateTask(UpdateTaskKind kind, Actor &actorFunction, typename Attribute< DependencyTypes >::Ptr... dependencies)
Definition Attribute.h:211
std::tuple< typename Attribute< DependencyTypes >::Ptr... > mDependencies
Definition Attribute.h:206
UpdateTaskKind mKind
Definition Attribute.h:208
virtual AttributeBase::List getDependencies() override
Definition Attribute.h:226
std::function< void(std::shared_ptr< DependentType > &, typename Attribute< DependencyTypes >::Ptr...)> Actor
Definition Attribute.h:201
static Complex polar(Real abs, Real phase)
Definition MathUtils.cpp:55
static Real phase(Complex value)
Definition MathUtils.cpp:23
static Real abs(Complex value)
Definition MathUtils.cpp:27
static std::shared_ptr< T > make(Args &&...args)
Definition PtrFactory.h:19
std::string String
Definition Definitions.h:65
UpdateTaskKind
Definition Attribute.h:27
@ UPDATE_ON_SIMULATION_STEP
Definition Attribute.h:31
@ UPDATE_ON_GET
Definition Attribute.h:29
@ UPDATE_ONCE
Definition Attribute.h:28
@ UPDATE_ON_SET
Definition Attribute.h:30
Eigen::Matrix< VarType, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixVar
Definition Definitions.h:97
std::complex< Real > Complex
Definition Definitions.h:63
bool operator()(CPS::AttributePointer< T > a, CPS::AttributePointer< T > b) const
Definition Attribute.h:101
bool operator()(CPS::AttributePointer< T > a, CPS::AttributePointer< T > b) const
Definition Attribute.h:111
size_t operator()(CPS::AttributePointer< T > const &x) const
Definition Attribute.h:694