Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
547cac8
Work in progress code for cosim integration
abdourahmanbarry Apr 21, 2026
7463300
Added partition interfaces to power electronics and updated cmake fil…
abdourahmanbarry Jun 1, 2026
ea84ec5
Made minor changes to partition interface code
abdourahmanbarry Jun 3, 2026
2dd8fe8
Updated Hires test problem to implicit form
abdourahmanbarry Jun 3, 2026
a0b7a50
Change comments in partition interfaces
abdourahmanbarry Jun 3, 2026
82c0efc
Added a subsystem model for evaluating partitions
abdourahmanbarry Jun 15, 2026
d5d84c5
Added a partitioned microgrid test problem
abdourahmanbarry Jun 15, 2026
1a8ba04
Updated bus partition interface to work with new SubsystemModel
abdourahmanbarry Jun 15, 2026
c9c64f2
Work in progress cosimulation implementation: in rought shape
abdourahmanbarry Jun 15, 2026
9692e57
Cleaned up code in subsystem and made the partition microgrid test ex…
abdourahmanbarry Jun 15, 2026
9950483
First attempt at arbitrary partitioning
abdourahmanbarry Jun 24, 2026
3609340
Added microgrid with four partitions
abdourahmanbarry Jun 24, 2026
5ef63d3
first version of subsystem
abdourahmanbarry Jun 24, 2026
c60ba33
Added partitioned scale microgrid example
abdourahmanbarry Jun 24, 2026
89ee325
Rmoved obsolete interfaces and clean up partitioning code
abdourahmanbarry Jun 26, 2026
1e99fc3
Partition Scale Microgrid configured with 10000IBRs
abdourahmanbarry Jun 27, 2026
5437b89
Added Jacobian contributions for bus interfaces
abdourahmanbarry Jul 6, 2026
5506d2b
Benchmark Setup for Parallel Function Evaluation
abdourahmanbarry Jun 27, 2026
288acab
Minor updates
abdourahmanbarry Jul 7, 2026
1e6a67e
Added subsystem Jacobian
abdourahmanbarry Jul 7, 2026
67eb9bc
Updated Hires test problem
abdourahmanbarry Jul 13, 2026
67435a5
Add subsystem Jacobian testing utilities and update partition test pr…
abdourahmanbarry Jul 13, 2026
c1e3bd4
Update partitioning code to work with recent changes in develop
abdourahmanbarry Jul 19, 2026
74ac54a
Updated copy constructor in circuit component
abdourahmanbarry Jul 20, 2026
0bd364a
Removed Neumaier Compensation
abdourahmanbarry Jul 20, 2026
3b62428
Updated Hires test problem
abdourahmanbarry Jul 20, 2026
261ea10
Removed print statements
abdourahmanbarry Jul 20, 2026
a8bf8bb
Apply pre-commit fixes
abdourahmanbarry Jul 20, 2026
1ba215c
Make SubsystemModel inherit from PowerElectronicsModel for code reuse
abdourahmanbarry Jul 23, 2026
eb528de
Apply pre-commit fixes
abdourahmanbarry Jul 23, 2026
6328a8a
Updated SubsystemModel and Partition interfaces
abdourahmanbarry Jul 24, 2026
96ac403
Updated examples to reflect new changes in subsystem model and partit…
abdourahmanbarry Jul 24, 2026
4ce744b
Apply pre-commit fixes
abdourahmanbarry Jul 24, 2026
1887bf0
Addressed leaks
abdourahmanbarry Jul 24, 2026
19a0a6f
Update partitioning code to use the no-copy implementation from develop
abdourahmanbarry Aug 3, 2026
7fa22d6
Apply pre-commit fixes
abdourahmanbarry Aug 3, 2026
23eeacf
Improve subsystem partitioning and bus interface handling
abdourahmanbarry Aug 6, 2026
2e360d9
Apply pre-commit fixes
abdourahmanbarry Aug 6, 2026
838af48
Update ChangeLog file
abdourahmanbarry Aug 6, 2026
c8a6dcb
Remove co-simulation changes for separate pull request
abdourahmanbarry Aug 6, 2026
f082543
Removed PartitionEvaluator
abdourahmanbarry Aug 11, 2026
6bb5472
Updated hires test problems
abdourahmanbarry Aug 11, 2026
367e193
Apply pre-commit fixes
abdourahmanbarry Aug 11, 2026
d87215d
Moved Hires test problem to tests folder
abdourahmanbarry Aug 15, 2026
7628dc5
Add more documentation for SubsystemModel
abdourahmanbarry Aug 15, 2026
f5c2134
Add clone function to components in PowerElectronics
abdourahmanbarry Aug 15, 2026
9053f17
Add tests for component clone method
abdourahmanbarry Aug 15, 2026
7c19edb
Generalize BusPartitionInterface
abdourahmanbarry Aug 15, 2026
9f85ee1
Fixed failing test
abdourahmanbarry Aug 15, 2026
93d0442
Refactored examples to minimize code duplication
abdourahmanbarry Aug 15, 2026
54af398
Cleaned up Microgrid examples
abdourahmanbarry Aug 15, 2026
938a7ff
Clean up
abdourahmanbarry Aug 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
- Added `HYGOV` governor model implementation for PhasorDynamics.
- Added `REPCA` controller model implementation for PhasorDynamics.
- Added `REECB` electrical-control model implementation for PhasorDynamics.
- Added subsystem partitioning support for `PowerElectronics` models, including partition interfaces, and independent residual and Jacobian evaluation.

## v0.1

Expand Down
2 changes: 2 additions & 0 deletions GridKit/Model/PowerElectronics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_subdirectory(TransmissionLine)
add_subdirectory(MicrogridLoad)
add_subdirectory(MicrogridLine)
add_subdirectory(MicrogridBusDQ)
add_subdirectory(PartitionInterface)

install(
FILES CircuitComponent.hpp
Expand All @@ -29,4 +30,5 @@ install(
SystemModelPowerElectronics.hpp
NodeBase.hpp
ExternalConnection.hpp
SubsystemModel.hpp
DESTINATION include/GridKit/Model/PowerElectronics)
31 changes: 31 additions & 0 deletions GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ namespace GridKit
return 0;
}

/**
* @brief Compute the absolute tolerance for each variable in the model
*
* @param rel_tol The relative tolerance which can be used to pick the
* absolute tolerance.
* @tparam ScalarT Scalar data type
* @tparam IdxT Index data type
* @return int 0 if successful, non-zero otherwise.
*
* This represents a "noise" level close to zero for which pure relative
* error cannot be used.
*/
template <class ScalarT, typename IdxT>
int Capacitor<ScalarT, IdxT>::setAbsoluteTolerance(RealT rel_tol)
{
abs_tol_.setToConst(static_cast<ScalarT>(rel_tol));
return 0;
}

/**
* @brief Evaluate the resisdual of the Capcitor
*
Expand Down Expand Up @@ -117,6 +136,18 @@ namespace GridKit
return 0;
}

template <class ScalarT, typename IdxT>
bool Capacitor<ScalarT, IdxT>::isCloneable() const
{
return true;
}

template <class ScalarT, typename IdxT>
CircuitComponent<ScalarT, IdxT>* Capacitor<ScalarT, IdxT>::clone() const
{
return new Capacitor<ScalarT, IdxT>(*this);
}

// Available template instantiations
template class Capacitor<double, long int>;
template class Capacitor<double, size_t>;
Expand Down
11 changes: 8 additions & 3 deletions GridKit/Model/PowerElectronics/Capacitor/Capacitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace GridKit
using CircuitComponent<ScalarT, IdxT>::y_int_;
using CircuitComponent<ScalarT, IdxT>::yp_ext_;
using CircuitComponent<ScalarT, IdxT>::yp_int_;
using CircuitComponent<ScalarT, IdxT>::abs_tol_;
using CircuitComponent<ScalarT, IdxT>::tag_;
using CircuitComponent<ScalarT, IdxT>::f_ext_;
using CircuitComponent<ScalarT, IdxT>::f_int_;
Expand All @@ -50,15 +51,19 @@ namespace GridKit

int initialize();
int tagDifferentiable();
int setAbsoluteTolerance(RealT);
int evaluateInternalResidual() final;
int evaluateExternalResidual() final;
int evaluateJacobian();
int evaluateIntegrand();

int initializeAdjoint();
int evaluateAdjointResidual();
int initializeAdjoint();
int evaluateAdjointResidual();
// int evaluateAdjointJacobian();
int evaluateAdjointIntegrand();
int evaluateAdjointIntegrand();
bool isCloneable() const;

CircuitComponent<ScalarT, IdxT>* clone() const;

private:
RealT C_;
Expand Down
215 changes: 210 additions & 5 deletions GridKit/Model/PowerElectronics/CircuitComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,138 @@ namespace GridKit

CircuitComponent() = default;

CircuitComponent(const CircuitComponent& other)
: n_extern_(other.n_extern_),
n_intern_(other.n_intern_),
extern_indices_(other.extern_indices_),
size_(other.size_),
nnz_(other.nnz_),
size_quad_(other.size_quad_),
size_opt_(other.size_opt_),
current_jac_size_(other.current_jac_size_),

// These pointers refer to storage supplied by a parent system.
// The copied component must be connected to its own storage later.
y_int_(nullptr),
yp_int_(nullptr),
f_int_(nullptr),

tag_(other.tag_),
time_(other.time_),
alpha_(other.alpha_),
max_steps_(other.max_steps_),
idc_(other.idc_),
allocated_(other.allocated_)
{
Comment thread
abdourahmanbarry marked this conversation as resolved.
/*
* VectorT disables its normal copy constructor and copy-assignment
* operator. Use its provided copyFromExternal() operation to perform
* an independent copy of the vector data.
*/
auto copyVector = [](VectorT& destination, const VectorT& source)
{
const IdxT source_size = source.getSize();

if (source_size == 0)
{
return;
}

destination.resize(source_size);
destination.copyFromExternal(source);
};

/*
* Deep-copy the local-to-global connection mapping.
*/
if (other.connection_nodes_)
{
connection_nodes_ = std::make_unique<IdxT[]>(static_cast<size_t>(size_));

for (IdxT i = 0; i < size_; ++i)
Comment thread
abdourahmanbarry marked this conversation as resolved.
{
connection_nodes_[static_cast<size_t>(i)] = other.connection_nodes_[static_cast<size_t>(i)];
}
}

/*
* Deep-copy the COO Jacobian row indices.
*/
if (other.jacobian_coo_rows_)
{
jacobian_coo_rows_ = std::make_unique<IdxT[]>(static_cast<size_t>(nnz_));

for (IdxT i = 0; i < nnz_; ++i)
{
jacobian_coo_rows_[static_cast<size_t>(i)] = other.jacobian_coo_rows_[static_cast<size_t>(i)];
}
}

/*
* Deep-copy the COO Jacobian column indices.
*/
if (other.jacobian_coo_cols_)
{
jacobian_coo_cols_ = std::make_unique<IdxT[]>(static_cast<size_t>(nnz_));

for (IdxT i = 0; i < nnz_; ++i)
{
jacobian_coo_cols_[static_cast<size_t>(i)] = other.jacobian_coo_cols_[static_cast<size_t>(i)];
}
}

/*
* Deep-copy the COO Jacobian values.
*/
if (other.jacobian_coo_values_)
{
jacobian_coo_values_ = std::make_unique<RealT[]>(static_cast<size_t>(nnz_));

for (IdxT i = 0; i < nnz_; ++i)
{
jacobian_coo_values_[static_cast<size_t>(i)] = other.jacobian_coo_values_[static_cast<size_t>(i)];
}
}

if (size_ > 0)
{
y_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
yp_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
f_ext_ = std::make_unique<ScalarT*[]>(static_cast<size_t>(size_));

for (IdxT i = 0; i < size_; ++i)
{
y_ext_[i] = nullptr;
yp_ext_[i] = nullptr;
f_ext_[i] = nullptr;
}
}

// State, state derivative, residual, and absolute tolerance.
copyVector(y_, other.y_);
copyVector(yp_, other.yp_);
copyVector(f_, other.f_);
copyVector(abs_tol_, other.abs_tol_);
copyVector(g_, other.g_);
copyVector(yB_, other.yB_);
copyVector(ypB_, other.ypB_);
copyVector(fB_, other.fB_);
copyVector(gB_, other.gB_);
copyVector(param_, other.param_);
copyVector(param_up_, other.param_up_);
copyVector(param_lo_, other.param_lo_);
Comment thread
abdourahmanbarry marked this conversation as resolved.
}

virtual CircuitComponent<ScalarT, IdxT>* clone() const
{
return nullptr;
}

virtual bool isCloneable() const
{
return false;
}

/**
* @note Cannot be marked final, since it is overriden to recurse in the system model.
*/
Expand All @@ -51,7 +183,7 @@ namespace GridKit
return this->n_intern_;
}

std::set<size_t> getExternIndices()
std::set<IdxT> getExternIndices()
{
return this->extern_indices_;
}
Expand All @@ -69,7 +201,7 @@ namespace GridKit
int setInternalConnectionNodes(size_t local_index, IdxT global_index)
{
assert(!extern_indices_.contains(static_cast<IdxT>(local_index)));
connection_nodes_[local_index] = global_index;
setConnectionNodes(local_index, global_index);
return 0;
}

Expand All @@ -95,6 +227,23 @@ namespace GridKit
return 0;
}

/**
* @brief Update the connection index for a variable.
*
* Changes only the connection index without modifying the variable's
* internal/external classification or its associated data pointers.
*
* @param local_index Index of the local variable.
* @param connection_index New connection index for the variable.
*
* @return int 0 if successful.
*/
int setConnectionNodes(size_t local_index, IdxT connection_index)
{
connection_nodes_[local_index] = connection_index;
return 0;
}

Comment on lines +230 to +246

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this function need to exist in addition to setInternalConnectionNodes? It's dangerous to set the connection_nodes_ of an external variables without setting its appropriate external pointers (as documented in setInternalConnectionNodes).

Also if it's entirely necessary, you can just remove the assert from setInternalConnectionNodes rather than creating an entirely new function.

/**
* @brief Given the location of value in the local vector map to global index
*
Expand Down Expand Up @@ -132,9 +281,10 @@ namespace GridKit
jacobian_coo_cols_ = std::make_unique<IdxT[]>(static_cast<size_t>(nnz_));
jacobian_coo_values_ = std::make_unique<RealT[]>(static_cast<size_t>(nnz_));

y_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
yp_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
f_ext_ = std::make_unique<ScalarT*[]>(static_cast<size_t>(size_));
y_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
yp_ext_ = std::make_unique<const ScalarT*[]>(static_cast<size_t>(size_));
f_ext_ = std::make_unique<ScalarT*[]>(static_cast<size_t>(size_));

connection_nodes_ = std::make_unique<IdxT[]>(static_cast<size_t>(size_));

if (!allocated_)
Expand Down Expand Up @@ -225,6 +375,51 @@ namespace GridKit
f_int_ = internal_res;
}

/**
* @brief Clear all internal and external data pointers.
*
* This disconnects the component from the data storage currently associated
* with its internal and external variables. The external pointer arrays
* themselves remain allocated so that the component can be connected to
* new data later.
*
* @return int 0 if successful.
*/
int clearPointers()
{
// Clear internal data pointers.
y_int_ = nullptr;
yp_int_ = nullptr;
f_int_ = nullptr;

// Clear external data pointers, but keep the pointer arrays allocated.
if (y_ext_)
{
for (IdxT i = 0; i < size_; ++i)
{
y_ext_[i] = nullptr;
}
}

if (yp_ext_)
{
for (IdxT i = 0; i < size_; ++i)
{
yp_ext_[i] = nullptr;
}
}

if (f_ext_)
{
for (IdxT i = 0; i < size_; ++i)
{
f_ext_[i] = nullptr;
}
}

return 0;
}

Comment thread
abdourahmanbarry marked this conversation as resolved.
protected:
/**
* @brief Reset the Jacobian so it can be constructed. Helper method for \ref setJacValues().
Expand Down Expand Up @@ -439,6 +634,16 @@ namespace GridKit
return idc_;
}

/**
* @brief Check whether the component has already been allocated.
*
* @return true if allocate() has previously completed, false otherwise.
*/
bool isAllocated() const
{
return allocated_;
}

Comment thread
abdourahmanbarry marked this conversation as resolved.
protected:
/**
* @brief Allocate state and residual storage owned by this component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,18 @@ namespace GridKit
return 0;
}

template <class ScalarT, typename IdxT>
bool DistributedGenerator<ScalarT, IdxT>::isCloneable() const
{
return true;
}

template <class ScalarT, typename IdxT>
CircuitComponent<ScalarT, IdxT>* DistributedGenerator<ScalarT, IdxT>::clone() const
{
return new DistributedGenerator<ScalarT, IdxT>(*this);
}

// Available template instantiations
template class DistributedGenerator<double, long int>;
template class DistributedGenerator<double, size_t>;
Expand Down
Loading