Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 25 additions & 0 deletions GridKit/Model/PowerElectronics/Capacitor/Capacitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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 @@ -119,6 +138,12 @@ namespace GridKit
return 0;
}

template <class ScalarT, typename IdxT>
CircuitComponent<ScalarT, IdxT>* Capacitor<ScalarT, IdxT>::clone() const
{
return new Capacitor<ScalarT, IdxT>(*this);
Comment thread
nkoukpaizan marked this conversation as resolved.
}

// Available template instantiations
template class Capacitor<double, long int>;
template class Capacitor<double, size_t>;
Expand Down
4 changes: 4 additions & 0 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,6 +51,7 @@ namespace GridKit

int initialize();
int tagDifferentiable();
int setAbsoluteTolerance(RealT);
int evaluateInternalResidual() final;
int evaluateExternalResidual() final;
int evaluateJacobian();
Expand All @@ -60,6 +62,8 @@ namespace GridKit
// int evaluateAdjointJacobian();
int evaluateAdjointIntegrand();

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

private:
RealT C_;
};
Expand Down
218 changes: 208 additions & 10 deletions GridKit/Model/PowerElectronics/CircuitComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cassert>
#include <memory>
#include <set>
#include <stdexcept>
#include <vector>

#include <GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp>
Expand All @@ -27,6 +28,176 @@ namespace GridKit

CircuitComponent() = default;

protected:
/**
* @brief Constructs a copy of a circuit component.
*
* Copies the component metadata, local vector data, connection-node mapping,
* and COO Jacobian storage. Dynamically allocated component-owned data is
* deep-copied so that the new component does not share ownership of this
* storage with @p other.
*
* Pointers to state, state-derivative, and residual storage supplied by a
* parent system are copied as-is. Consequently, the copied component initially
* references the same parent-system storage as @p other. The pointer arrays
* used for external variables are independently allocated, but their entries
* point to the same external state, state-derivative, and residual storage as
* the original component.
*
* Local vectors, including the state, state derivative, residual, tolerances,
* quadrature data, adjoint data, and parameter vectors, retain the values of
* the original component.
*
* @param other Component to copy.
*
* @note If the copied component is subsequently attached to a different parent
* system, its state, state-derivative, and residual pointers must be
* reassigned to the storage provided by that system before evaluation.
*/
CircuitComponent(const CircuitComponent& other)
Comment thread
nkoukpaizan marked this conversation as resolved.
: 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_),
y_int_(other.y_int_),
yp_int_(other.yp_int_),
f_int_(other.f_int_),
tag_(other.tag_),
time_(other.time_),
alpha_(other.alpha_),
max_steps_(other.max_steps_),
idc_(other.idc_),
allocated_(other.allocated_)
{

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 (size_t i = 0; i < static_cast<size_t>(size_); ++i)
{
connection_nodes_[i] = other.connection_nodes_[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 (size_t i = 0; i < static_cast<size_t>(nnz_); ++i)
{
jacobian_coo_rows_[i] = other.jacobian_coo_rows_[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 (size_t i = 0; i < static_cast<size_t>(nnz_); ++i)
{
jacobian_coo_cols_[i] = other.jacobian_coo_cols_[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 (size_t i = 0; i < static_cast<size_t>(nnz_); ++i)
{
jacobian_coo_values_[i] = other.jacobian_coo_values_[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 (size_t i = 0; i < static_cast<size_t>(size_); ++i)
{
y_ext_[i] = other.y_ext_[i];
yp_ext_[i] = other.yp_ext_[i];
f_ext_[i] = other.f_ext_[i];
}
}

// 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_);
}

public:
/**
* @brief Create an independent copy of this component.
*
* The clone preserves the component's model configuration, parameters,
* topology, and structural data, but does not preserve bindings to
* system-owned state or residual storage.
*
* @note By default, the cloned component's state, state-derivative, and
* residual pointers are not set. The user is responsible for setting these
* pointers to the appropriate storage before evaluating the residual.
*/
virtual CircuitComponent<ScalarT, IdxT>* clone() const
{
throw std::runtime_error("clone() is not supported for this component.");
}

/**
* @brief Indicates whether this component supports cloning.
*
* Derived components that implement clone() should override this method
* and return true.
*
* @return true if the component can be cloned, false otherwise.
*/
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 +222,7 @@ namespace GridKit
return this->n_intern_;
}

std::set<size_t> getExternIndices()
std::set<IdxT> getExternIndices()
{
return this->extern_indices_;
}
Expand All @@ -69,7 +240,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 @@ -88,10 +259,27 @@ namespace GridKit
int setExternalConnectionNodes(size_t local_index, ExternalConnection<ScalarT, IdxT> connection)
{
assert(extern_indices_.contains(local_index));
y_ext_[local_index] = connection.y_;
yp_ext_[local_index] = connection.yp_;
f_ext_[local_index] = connection.f_;
connection_nodes_[local_index] = connection.idx_;
y_ext_[local_index] = connection.y_;
yp_ext_[local_index] = connection.yp_;
f_ext_[local_index] = connection.f_;
setConnectionNodes(local_index, connection.idx_);
return 0;
}

/**
* @brief Update the connection index for a variable.
*
* Sets 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;
}

Expand Down Expand Up @@ -132,9 +320,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_));

tag_.resize(static_cast<size_t>(size_));
Expand Down Expand Up @@ -441,6 +630,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_;
}

protected:
/**
* @brief Allocate state and residual storage owned by this component.
Expand Down Expand Up @@ -491,7 +690,6 @@ namespace GridKit
*/
std::unique_ptr<IdxT[]> connection_nodes_;

protected:
/// The number of variables in this component. Should be equal to \ref n_extern_ plus \ref n_intern_. \see size()
IdxT size_{0};
/// The number of nonzero elements in this component's Jacobian. \see nnz()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,12 @@ namespace GridKit
return 0;
}

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
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ namespace GridKit
// int evaluateAdjointJacobian();
int evaluateAdjointIntegrand();

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

private:
RealT wb_;
RealT wc_;
Expand Down
25 changes: 25 additions & 0 deletions GridKit/Model/PowerElectronics/InductionMotor/InductionMotor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,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 InductionMotor<ScalarT, IdxT>::setAbsoluteTolerance(RealT rel_tol)
{
abs_tol_.setToConst(static_cast<ScalarT>(rel_tol));
return 0;
}

/**
* @brief Contributes to the resisdual
*
Expand Down Expand Up @@ -131,6 +150,12 @@ namespace GridKit
return 0;
}

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

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