Repository navigation
Add Subsystem and Partition Interfaces for PowerElectronics - #560
abdourahmanbarry wants to merge 38 commits into
Conversation
45b0f43 to
c90bae2
Compare
superwhiskers
left a comment
There was a problem hiding this comment.
just an architectural question
6b976de to
1ad85a7
Compare
1ad85a7 to
e23c7ba
Compare
nkoukpaizan
left a comment
There was a problem hiding this comment.
A few specific comments.
This seems to work, but I find the logic of the BusPartitionInterface constructor and SubsystemModel index maps hard to follow. I would like to get inputs from @alexander-novo on those implementations.
I'll take another look after the initial comments have been addressed.
|
@nkoukpaizan @alexander-novo @superwhiskers I have updated the code to incorporate the suggestions and improved the documentation to make the implementation easier to follow. Let me know what you think. |
superwhiskers
left a comment
There was a problem hiding this comment.
just one minor comment
|
@nkoukpaizan I have added the partition interface that we discussed last time. It is simpler (and hopefully more efficient), but it only supports partitioning between a |
superwhiskers
left a comment
There was a problem hiding this comment.
looks good. all of these are nitpicks. SubsystemModelWithHires passes just fine on my machine.
nkoukpaizan
left a comment
There was a problem hiding this comment.
I like the BusLinePartitionInterface. Please see my related comments and other comments below.
33726c6 to
cde9d74
Compare
nkoukpaizan
left a comment
There was a problem hiding this comment.
A few minor comments. Good to merge after they are addressed.
| public: | ||
| using TimeFunction = std::function<void(ScalarT)>; |
There was a problem hiding this comment.
I believe the argument should be RealT rather than ScalarT. Does the alias need to be public?
There was a problem hiding this comment.
This is address in 60060e8
I left the alias as public as it is used by one of the methods as a parameter type. But it can be made private as well if that is preferable.
There was a problem hiding this comment.
Yes, let's keep it private.
There was a problem hiding this comment.
Okay, sounds great.
There was a problem hiding this comment.
This looks good; there are only a few minor things to address before we merge:
Please address comments by @nkoukpaizan and a few comments here (mainly questions on implementation). If the code is intentionally implemented like this, please add comments explaining why. The implementation intent at places I flagged is not quite clear to me.
| /** | ||
| *@brief Maps global system connection indices to local subsystem connection indices. | ||
| */ | ||
| std::unordered_map<IdxT, IdxT> global_to_local_map_; |
There was a problem hiding this comment.
Why use map here? Why not use vector with mapping indices?
There was a problem hiding this comment.
The reason for using a map here is that the keys(global indices) belonging to a partition may not necessarily be contiguous. I am afraid using a vector could require create a large vector, even though only a small fraction of its entries would be used.
| ~PartitionInterface() = default; | ||
| }; |
There was a problem hiding this comment.
I believe it should be:
| ~PartitionInterface() = default; | |
| }; | |
| ~PartitionInterface() override = default; | |
| }; |
| for (component_type* comp : components_) | ||
| { | ||
| auto extern_indices = comp->getExternIndices(); | ||
|
|
||
| for (IdxT j = 0; j < comp->size(); j++) | ||
| { | ||
| if (extern_indices.contains(j)) |
There was a problem hiding this comment.
Could we have instead:
| for (component_type* comp : components_) | |
| { | |
| auto extern_indices = comp->getExternIndices(); | |
| for (IdxT j = 0; j < comp->size(); j++) | |
| { | |
| if (extern_indices.contains(j)) | |
| for (component_type* comp : components_) | |
| { | |
| const auto& extern_indices = comp->getExternIndices(); | |
| for (IdxT j = 0; j < comp->size(); j++) | |
| { | |
| if (extern_indices.contains(j)) |
| for (node_type* node : nodes_) | ||
| { | ||
| for (IdxT i = 0; i < node->size(); i++) | ||
| { | ||
| const IdxT global_connection = node->getNodeConnection(i).idx_; | ||
|
|
||
| if (global_connection != INVALID_INDEX<IdxT>) | ||
| { | ||
| global_to_local_map_[global_connection] = local_connection++; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Here, in function buildConnectionMap(), i loops from 0 to node->size(). In allocate(), it loops from 0 to node->getInternalSize(). Why discrepancy?
There was a problem hiding this comment.
These two are the same in this case. However, it is good to be consistent. Thank you.
This is addressed here: 60060e8
| // Map each node's global connection indices to subsystem-local indices, | ||
| // then set the corresponding state, derivative, and residual pointers. | ||
| for (node_type* node : nodes_) | ||
| { | ||
| for (IdxT i = 0; i < static_cast<IdxT>(node->getInternalSize()); i++) | ||
| { | ||
| const IdxT node_global_connection = node->getNodeConnection(i).idx_; | ||
| const IdxT node_local_connection = global_to_local_map_.at(node_global_connection); | ||
|
|
There was a problem hiding this comment.
Her in allocate() function, i loops from 0 to node->getInternalSize(), whereas in buildConnectionMap(), an equivalent call loops from 0 to node->size(). Is this intended?
There was a problem hiding this comment.
Like the previous comment, this has been addressed here: 60060e8
|
One compiler warning to fix: The rest of the code compiles cleanly. All tests pass. |
- Update method comments - Make node size calls consistent - Change parameter type in ForcingFunction to RealT
|
|
||
| #pragma once | ||
|
|
||
| #include <omp.h> |
There was a problem hiding this comment.
| #include <omp.h> |
This should not be needed and fails on my machine with GRIDKIT_ENABLE_OPENMP=Off
GridKit/tests/UnitTests/PowerElectronics/PartitionPowerElectronicsTests.hpp:4:10: fatal error: 'omp.h' file not found
4 | #include <omp.h>
| ^~~~~~~
There was a problem hiding this comment.
That's right. This is address in the following commits.
Description
In this PR, we implement
SubsystemModelfor partitioned Power Electronics simulation. The implementation provides the infrastructure required to partition Power Electronics networks, and to evaluate subsystem residuals and Jacobians independently.This is the third of four stacked pull requests that split PR #492 into simpler, more manageable chunks.
Proposed changes
We added a
SubsystemModelclass to represent an individual partition and aBusPartitionInterfacecomponent to mark partition boundaries. Together, these enable us to partition larger networks for co-simulation and parallel function evaluation.Checklist
-Wall -Wpedantic -Wconversion -Wextra.