Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
- Added `REECB` electrical-control model implementation for PhasorDynamics.
- Added cases and validation for ACTIVSg10k, ACTIVSg200, ACTIVSg500, and WECC240.
- Added IDA option to choose the consistent initial condition calculation type.
- Implemented `tagDifferentiable()` for `PowerElectronics` models.

## v0.1

Expand Down
2 changes: 2 additions & 0 deletions GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int Capacitor<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions GridKit/Model/PowerElectronics/CircuitComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ namespace GridKit
f_ext_ = std::make_unique<ScalarT*[]>(static_cast<size_t>(size_));
connection_nodes_ = std::make_unique<IdxT[]>(static_cast<size_t>(size_));

tag_.resize(static_cast<size_t>(size_));

if (!allocated_)
{
allocateVectors(size_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "DistributedGenerator.hpp"

#include <cmath>
#include <iostream>
#include <vector>

namespace GridKit
Expand Down Expand Up @@ -74,6 +73,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int DistributedGenerator<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int InductionMotor<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions GridKit/Model/PowerElectronics/Inductor/Inductor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int Inductor<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int LinearTransformer<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ namespace GridKit
return 0;
}

/*
* \brief Identify differential variables
*/
/// There are no internal variables in this component, so \ref tag_ can be set arbitrarily.
template <class ScalarT, typename IdxT>
int MicrogridBusDQ<ScalarT, IdxT>::tagDifferentiable()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int MicrogridLine<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int MicrogridLoad<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion GridKit/Model/PowerElectronics/NodeBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ namespace GridKit
allocateVectors(static_cast<IdxT>(size));
}

tag_.resize(size);
tag_.resize(size, false);
variable_indices_.resize(size);
residual_indices_.resize(size);

Expand Down
4 changes: 1 addition & 3 deletions GridKit/Model/PowerElectronics/Resistor/Resistor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ namespace GridKit
return 0;
}

/*
* \brief Identify differential variables
*/
/// There are no internal variables in this component, so \ref tag_ can be set arbitrarily.
template <class ScalarT, typename IdxT>
Comment thread
nkoukpaizan marked this conversation as resolved.
int Resistor<ScalarT, IdxT>::tagDifferentiable()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int SynchronousMachine<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are differentials
std::fill(tag_.begin(), tag_.end(), true);
return 0;
}

Expand Down
47 changes: 47 additions & 0 deletions GridKit/Model/PowerElectronics/SystemModelPowerElectronics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,55 @@ namespace GridKit
return CircuitComponent<ScalarT, IdxT>::initialize();
}

/**
* @brief Tags all system variables as differentiable, based on what the
* components that own those variables tag them as.
*
* Starts by asking all components to tag their differentiables. This implementation
* assumes all node variables are algebraic, and will not ask nodes to tag their differentiables.
* Sets all variables to algebraic (`false`) to start, then loops over all component internal variables.
* Re-creates the same internal variable to system variables mapping as in \ref allocate() - all
* internal variables from the same component are stored contiguously in a block, and blocks are
* stored contiguously in the same order as \ref components_, with node variables at the end.
* Each internal variable's tag in the system is set to its tag in the component.
*/
int tagDifferentiable() final
{
// Ask all component to tag their differentiables
for (size_t i = 0; i < components_.size(); i++)
{
component_type* component = components_[i];

// Bubble up errors if necessary
if (int err = component->tagDifferentiable())
{
return err;
}
}

// Fill tags with a default value (false) for node variables. Assumed to be algebraic here.
std::fill(tag_.begin(), tag_.end(), false);

// Copy tags for internal variables from their components - going in the order as described above
size_t idx = 0;
for (component_type* comp : components_)
{
const auto& external_indices = comp->getExternIndices();

// Loop over all component variables - including externals
for (IdxT i = 0; i < comp->size(); i++)
{
// Discard externals
if (!external_indices.contains(i))
{
tag_[idx] = comp->tag()[i];

// Ensures internal variables are contiguous, and in the same order as the component
idx++;
}
}
}
Comment thread
alexander-novo marked this conversation as resolved.

return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int TransmissionLine<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are algebraics
std::fill(tag_.begin(), tag_.end(), false);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace GridKit
template <class ScalarT, typename IdxT>
int VoltageSource<ScalarT, IdxT>::tagDifferentiable()
{
// All variables are algebraics
std::fill(tag_.begin(), tag_.end(), false);
return 0;
}

Expand Down
27 changes: 27 additions & 0 deletions examples/PowerElectronics/Microgrid/Microgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,33 @@ int main(int /* argc */, char const** /* argv */)
sysmodel->getCsrJacobian()->print();
}

sysmodel->tagDifferentiable();

bool all_internal_diff = true;
bool all_external_alg = true;

const size_t num_node_vars = bus1.size() + bus2.size() + bus3.size() + bus4.size() + dg_signal.size();

for (size_t i = 0; i < sysmodel->size() - num_node_vars; i++)
{
all_internal_diff = all_internal_diff && sysmodel->tag()[i];
if (!sysmodel->tag()[i])
{
std::cout << "Unexepected algebraic-tagged internal variable found in index " << i << '\n';
}
}

for (size_t i = sysmodel->size() - num_node_vars; i < sysmodel->size(); i++)
{
all_external_alg = all_external_alg && !sysmodel->tag()[i];
if (sysmodel->tag()[i])
{
std::cout << "Unexepected differential-tagged external variable found in index " << i << '\n';
}
}

std::cout << "Verify all internal variables are differential: " << all_internal_diff << ", and all external variables are algebraic: " << all_external_alg << '\n';

// Create numerical integrator and configure it for the generator model
auto* idas = new AnalysisManager::Sundials::Ida<double, size_t>(sysmodel);

Expand Down
Loading