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::forward<typename Attribute<DependencyTypes>::Ptr>(
214 dependencies)...),
215 mActorFunction(actorFunction), mKind(kind) {}
216
217 virtual void
218 executeUpdate(std::shared_ptr<DependentType> &dependent) override {
220 dependent,
221 std::get<typename Attribute<DependencyTypes>::Ptr...>(mDependencies));
222 }
223
228 return std::apply(
229 [](auto &&...elems) {
230 return std::vector<AttributeBase::Ptr>{
231 std::forward<decltype(elems)>(elems)...};
232 },
234 };
235};
236
241template <class T>
243 public std::enable_shared_from_this<Attribute<T>> {
244
245protected:
246 std::shared_ptr<T> mData;
247
248public:
249 using Type = T;
251
252 Attribute(T initialValue = T())
253 : AttributeBase(), mData(std::make_shared<T>()) {
254 *mData = initialValue;
255 }
256
261 virtual void set(T value) = 0;
262
266 virtual T &get() = 0;
267
274 virtual void setReference(Attribute<T>::Ptr reference) = 0;
275
280 virtual std::shared_ptr<T> asRawPointer() = 0;
281
285 String toString() override {
286 std::stringstream ss;
287 ss << this->get();
288 return ss.str();
289 }
290
301 operator const T &() { return this->get(); }
302
308 T &operator*() { return this->get(); }
309
314 bool copyValue(AttributeBase::Ptr copyFrom) override {
315 Attribute<T>::Ptr copyFromTyped =
316 std::dynamic_pointer_cast<Attribute<T>>(copyFrom.getPtr());
317 if (copyFromTyped.getPtr() == nullptr) {
318 return false;
319 }
320 this->set(**copyFromTyped);
321 return true;
322 }
323
328 const std::type_info &getType() override { return typeid(T); }
329
337 // TODO: This is in the real time path. We should not use heap here.
338 };
339
348 template <class U>
349 typename Attribute<U>::Ptr
352 typename AttributeUpdateTask<U, T>::Actor setter =
354 auto derivedAttribute = std::make_shared<AttributeDynamic<U>>();
355 if (setter) {
356 derivedAttribute->addTask(
360 Attribute<T>::Ptr(this->shared_from_this())));
361 }
362 if (getter) {
363 derivedAttribute->addTask(
367 Attribute<T>::Ptr(this->shared_from_this())));
368 }
369 return derivedAttribute;
370 }
371
376 template <typename U = T,
377 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
379 // requires std::same_as<T, CPS::Complex> //CPP20
380 {
382 [](std::shared_ptr<Real> &dependent,
383 typename Attribute<Complex>::Ptr dependency) {
384 *dependent = (**dependency).real();
385 };
387 [](std::shared_ptr<Real> &dependent,
388 typename Attribute<Complex>::Ptr dependency) {
389 CPS::Complex currentValue = dependency->get();
390 currentValue.real(*dependent);
391 dependency->set(currentValue);
392 };
393 return derive<CPS::Real>(getter, setter);
394 }
395
400 template <typename U = T,
401 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
403 // requires std::same_as<T, CPS::Complex> //CPP20
404 {
406 [](std::shared_ptr<Real> &dependent,
407 Attribute<Complex>::Ptr dependency) {
408 *dependent = (**dependency).imag();
409 };
411 [](std::shared_ptr<Real> &dependent,
412 Attribute<Complex>::Ptr dependency) {
413 CPS::Complex currentValue = dependency->get();
414 currentValue.imag(*dependent);
415 dependency->set(currentValue);
416 };
417 return derive<CPS::Real>(getter, setter);
418 }
419
424 template <typename U = T,
425 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
427 // requires std::same_as<T, CPS::Complex> //CPP20
428 {
430 [](std::shared_ptr<Real> &dependent,
431 Attribute<Complex>::Ptr dependency) {
432 *dependent = Math::abs(**dependency);
433 };
435 [](std::shared_ptr<Real> &dependent,
436 Attribute<Complex>::Ptr dependency) {
437 CPS::Complex currentValue = dependency->get();
438 dependency->set(Math::polar(*dependent, Math::phase(currentValue)));
439 };
440 return derive<CPS::Real>(getter, setter);
441 }
442
447 template <typename U = T,
448 std::enable_if_t<std::is_same_v<Complex, U>, bool> = true>
450 // requires std::same_as<T, CPS::Complex> //CPP20
451 {
453 [](std::shared_ptr<Real> &dependent,
454 Attribute<Complex>::Ptr dependency) {
455 *dependent = Math::phase(**dependency);
456 };
458 [](std::shared_ptr<Real> &dependent,
459 Attribute<Complex>::Ptr dependency) {
460 CPS::Complex currentValue = dependency->get();
461 dependency->set(Math::polar(Math::abs(currentValue), *dependent));
462 };
463 return derive<CPS::Real>(getter, setter);
464 }
465
471 template <typename U = T, std::enable_if_t<std::is_same_v<Real, U> ||
472 std::is_same_v<Complex, U>,
473 bool> = true>
475 // requires std::same_as<T, CPS::Complex> || std::same_as<T, CPS::Real> //CPP20
476 {
477 typename AttributeUpdateTask<T, T>::Actor getter =
478 [scale](std::shared_ptr<T> &dependent, Attribute<T>::Ptr dependency) {
479 *dependent = scale * (**dependency);
480 };
481 typename AttributeUpdateTask<T, T>::Actor setter =
482 [scale](std::shared_ptr<T> &dependent, Attribute<T>::Ptr dependency) {
483 dependency->set((*dependent) / scale);
484 };
485 return derive<T>(getter, setter);
486 }
487
495 template <class U, class V = T,
496 std::enable_if_t<std::is_same_v<CPS::MatrixVar<U>, V>, bool> = true>
499 typename CPS::MatrixVar<U>::Index column)
500 // requires std::same_as<T, CPS::MatrixVar<U>> //CPP20
501 {
502 typename AttributeUpdateTask<U, T>::Actor getter =
503 [row, column](std::shared_ptr<U> &dependent,
504 Attribute<T>::Ptr dependency) {
505 *dependent = (**dependency)(row, column);
506 };
507 typename AttributeUpdateTask<U, T>::Actor setter =
508 [row, column](std::shared_ptr<U> &dependent,
509 Attribute<T>::Ptr dependency) {
510 CPS::MatrixVar<U> currentValue = dependency->get();
511 currentValue(row, column) = *dependent;
512 dependency->set(currentValue);
513 };
514 return derive<U>(getter, setter);
515 }
516};
517
522template <class T>
523class AttributeStatic : public Attribute<T>,
524 public SharedFactory<AttributeStatic<T>> {
525 friend class SharedFactory<AttributeStatic<T>>;
526
527public:
528 AttributeStatic(T initialValue = T()) : Attribute<T>(initialValue) {}
529
530 virtual void set(T value) override { *this->mData = value; };
531
532 virtual T &get() override { return *this->mData; };
533
534 virtual bool isStatic() const override { return true; }
535
536 virtual void setReference(typename Attribute<T>::Ptr reference) override {
537 throw TypeException();
538 }
539
540 virtual std::shared_ptr<T> asRawPointer() override { return this->mData; }
541
542 virtual void appendDependencies(AttributeBase::Set *deps) override {
543 deps->insert(this->shared_from_this());
544 }
545};
546
550template <class T>
551class AttributeDynamic : public Attribute<T>,
552 public SharedFactory<AttributeDynamic<T>> {
553 friend class SharedFactory<AttributeDynamic<T>>;
554
555protected:
556 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnce;
557 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnGet;
558 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnSet;
559
560public:
561 AttributeDynamic(T initialValue = T()) : Attribute<T>(initialValue) {}
562
569 typename AttributeUpdateTaskBase<T>::Ptr task) {
570 switch (kind) {
572 updateTasksOnce.push_back(task);
573 // THISISBAD: This is probably not the right time to run this kind of task
574 task->executeUpdate(this->mData);
575 break;
577 updateTasksOnGet.push_back(task);
578 break;
580 updateTasksOnSet.push_back(task);
581 break;
584 };
585 }
586
592 switch (kind) {
594 updateTasksOnce.clear();
595 break;
597 updateTasksOnGet.clear();
598 break;
600 updateTasksOnSet.clear();
601 break;
604 };
605 }
606
611 updateTasksOnce.clear();
612 updateTasksOnGet.clear();
613 updateTasksOnSet.clear();
614 }
615
616 virtual void setReference(typename Attribute<T>::Ptr reference) override {
617 typename AttributeUpdateTask<T, T>::Actor getter =
618 [](std::shared_ptr<T> &dependent,
619 typename Attribute<T>::Ptr dependency) {
620 dependent = dependency->asRawPointer();
621 };
622 this->clearAllTasks();
623 if (reference->isStatic()) {
626 getter, reference));
627 } else {
630 UpdateTaskKind::UPDATE_ON_GET, getter, reference));
631 }
632 }
633
634 virtual std::shared_ptr<T> asRawPointer() override {
636 task->executeUpdate(this->mData);
637 }
638 return this->mData;
639 }
640
641 virtual void set(T value) override {
642 *this->mData = value;
644 task->executeUpdate(this->mData);
645 }
646 };
647
648 virtual T &get() override {
650 task->executeUpdate(this->mData);
651 }
652 return *this->mData;
653 };
654
655 virtual bool isStatic() const override { return false; }
656
662 virtual void appendDependencies(AttributeBase::Set *deps) override {
663 deps->insert(this->shared_from_this());
664
667 AttributeBase::List taskDeps = task->getDependencies();
668 newDeps.insert(taskDeps.begin(), taskDeps.end());
669 }
670
672 AttributeBase::List taskDeps = task->getDependencies();
673 newDeps.insert(taskDeps.begin(), taskDeps.end());
674 }
675
676 for (auto dependency : newDeps) {
677 dependency->appendDependencies(deps);
678 }
679 }
680};
681
683
685
687
688} // namespace CPS
689
690namespace std {
694template <typename T> struct hash<CPS::AttributePointer<T>> {
695 size_t operator()(CPS::AttributePointer<T> const &x) const {
696 return std::hash<std::shared_ptr<T>>()(x.getPtr());
697 }
698};
699} // 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:561
void addTask(UpdateTaskKind kind, typename AttributeUpdateTaskBase< T >::Ptr task)
Definition Attribute.h:568
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnGet
Definition Attribute.h:557
virtual void setReference(typename Attribute< T >::Ptr reference) override
Definition Attribute.h:616
virtual void appendDependencies(AttributeBase::Set *deps) override
Definition Attribute.h:662
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnSet
Definition Attribute.h:558
std::vector< typename AttributeUpdateTaskBase< T >::Ptr > updateTasksOnce
Definition Attribute.h:556
void clearTasks(UpdateTaskKind kind)
Definition Attribute.h:591
virtual void set(T value) override
Definition Attribute.h:641
virtual std::shared_ptr< T > asRawPointer() override
Definition Attribute.h:634
virtual bool isStatic() const override
Definition Attribute.h:655
virtual T & get() override
Definition Attribute.h:648
const std::type_info & getType() override
Get the type of this attribute.
Definition Attribute.h:328
T & operator*()
User-defined dereference operator.
Definition Attribute.h:308
AttributePointer< Attribute< T > > deriveScaled(T scale)
Definition Attribute.h:474
Attribute(T initialValue=T())
Definition Attribute.h:252
AttributePointer< Attribute< Real > > deriveImag()
Definition Attribute.h:402
AttributePointer< Attribute< Real > > derivePhase()
Definition Attribute.h:449
AttributePointer< Attribute< U > > deriveCoeff(typename CPS::MatrixVar< U >::Index row, typename CPS::MatrixVar< U >::Index column)
Definition Attribute.h:498
virtual std::shared_ptr< T > asRawPointer()=0
AttributePointer< Attribute< Real > > deriveReal()
Definition Attribute.h:378
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:285
AttributeBase::Ptr cloneValueOntoNewAttribute() override
Generates a new attribute of the same type and copies the current value in the heap....
Definition Attribute.h:334
virtual T & get()=0
AttributePointer< Attribute< Real > > deriveMag()
Definition Attribute.h:426
bool copyValue(AttributeBase::Ptr copyFrom) override
Copy the attribute value of copyFrom onto this attribute.
Definition Attribute.h:314
std::shared_ptr< T > mData
Definition Attribute.h:246
AttributePointer< Attribute< T > > Ptr
Definition Attribute.h:250
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:350
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:530
virtual std::shared_ptr< T > asRawPointer() override
Definition Attribute.h:540
virtual void appendDependencies(AttributeBase::Set *deps) override
Definition Attribute.h:542
AttributeStatic(T initialValue=T())
Definition Attribute.h:528
virtual void setReference(typename Attribute< T >::Ptr reference) override
Definition Attribute.h:536
virtual bool isStatic() const override
Definition Attribute.h:534
virtual T & get() override
Definition Attribute.h:532
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:218
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:227
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:695