diff --git a/src/LinearAlgebra/SparsityPattern/Variable.hpp b/src/LinearAlgebra/SparsityPattern/Variable.hpp new file mode 100644 index 000000000..cb1321393 --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/Variable.hpp @@ -0,0 +1,337 @@ +/** + \file Variable.hpp +*/ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace GridKit +{ +namespace Sparse +{ + + /** + @brief The Variable class is used to store the unknowns of the + system and define abstract elementary algebra. + + \author Stefan Klus + \author Slaven Peles + */ + class Variable + { + public: + /** + @brief Default constructor. + */ + Variable() + : value_(0.0), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap) + { + } + + /** + @brief Constructor which initializes the value. + */ + explicit Variable(double value) + : value_(value), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap) + { + } + + /** + @brief Constructor which initializes the value and variable + number. + + */ + Variable(double value, size_t variable_number) + : value_(value), + variable_number_(variable_number), + is_fixed_(false), + dependencies_(new DependencyMap) + { + (*dependencies_)[variable_number_] = 1.0; + } + + /** + @brief Copy constructor. + */ + Variable(const Variable& v) + : value_(v.value_), + variable_number_(INVALID_VAR_NUMBER), + is_fixed_(false), + dependencies_(new DependencyMap(*v.dependencies_)) + { + } + + /** + @brief Destructor deletes the dependency map. + */ + ~Variable() + { + delete dependencies_; + } + + /** + @brief Assignment operator. Assigning double value to + Variable removes its dependencies. Use only if you know + what you are doing. + */ + Variable& operator=(const double& rhs) + { + value_ = rhs; + + dependencies_->clear(); + return *this; + } + + /** + @brief Assignment operator. + + This operator: + - assigns value from the right hand side + - leaves variable ID unchanged + - clears any existing and adds new dependencies from rhs + */ + Variable& operator=(const Variable& rhs) + { + if (this == &rhs) // self-assignment + return *this; + + // set value from rhs + value_ = rhs.value_; + + // if rhs is a constant so is *this + setFixed(rhs.is_fixed()); + + // set dependencies from rhs + dependencies_->clear(); // clear map just in case + addDependencies(rhs); // use only dependencies from the rhs + + return *this; + } + + + /** + @brief Operator () returns the value of a variable. + + This is just short notation to avoid using + getValue and setValue. + */ + double& operator()() + { + return value_; + } + + /** + @brief Operator() returns the value of a variable + (const version). + + This is just short notation to avoid using getValue. + */ + const double& operator()() const + { + return value_; + } + + /** + @brief Return the current value of the variable. + */ + double getValue() const + { + return value_; + } + + /** + @brief Overwrite the current value of the variable. + */ + void setValue(double value) + { + value_ = value; + } + + /** + @brief Return derivative of *this with respect to + dependency i. + */ + double der(size_t i) const + { + return (*dependencies_)[i]; + } + + + /** + @brief Returns the variable number. + + This number is assigned to state variables (variables + updated directly by the solver) only. + */ + size_t getVariableNumber() const + { + return variable_number_; + } + + /** + @brief Sets the variable number. + */ + void setVariableNumber(size_t variable_number) + { + dependencies_->clear(); + variable_number_ = variable_number; + (*dependencies_)[variable_number_] = 1.0; + } + + /** + @brief Checks whether the variable was registered as + an unknown of the system. + + INVALID_VAR_NUMBER is used to mark parameters and + temporary variables + */ + bool isRegistered() const + { + return variable_number_ != INVALID_VAR_NUMBER; + } + + /** + @brief Checks whether the variable is fixed or not. + */ + bool is_fixed() const + { + return is_fixed_; + } + + /** + @brief Turns variable into parameter, or vice versa. + */ + void setFixed(bool b = false) + { + is_fixed_ = b; + } + + + // get the 'input set' of a variable + using DependencyMap = std::map; + inline const DependencyMap& getDependencies() const; + + // set as the independent state variable and assign ID to it + inline void registerVariable(std::vector& x, + const size_t& offset); + + // adds all dependencies of v to *this + inline void addDependencies(const Variable& v); + + // scale dependencies (derivatives) by scalar @a c. + inline void scaleDependencies(double c); + + // print to output stream + inline void print(std::ostream& os) const; + + // += + inline Variable& operator+=(const double& rhs); + inline Variable& operator+=(const Variable& rhs); + + // -= + inline Variable& operator-=(const double& rhs); + inline Variable& operator-=(const Variable& rhs); + + // *= + inline Variable& operator*=(const double& rhs); + inline Variable& operator*=(const Variable& rhs); + + // /= + inline Variable& operator/=(const double& rhs); + inline Variable& operator/=(const Variable& rhs); + + + private: + double value_; ///< Value of the variable. + size_t variable_number_; ///< Independent variable ID + bool is_fixed_; ///< Constant parameter flag. + + mutable DependencyMap* dependencies_; + static const size_t INVALID_VAR_NUMBER = static_cast(-1); + }; + + //------------------------------------ + // non-member operators and functions + //------------------------------------ + + // unary - + inline const Variable operator-(const Variable& v); + + // + + inline const Variable operator+(const Variable& lhs, const Variable& rhs); + inline const Variable operator+(const Variable& lhs, const double& rhs); + inline const Variable operator+(const double& lhs, const Variable& rhs); + + // - + inline const Variable operator-(const Variable& lhs, const Variable& rhs); + inline const Variable operator-(const Variable& lhs, const double& rhs); + inline const Variable operator-(const double& lhs, const Variable& rhs); + + // * + inline const Variable operator*(const Variable& lhs, const Variable& rhs); + inline const Variable operator*(const Variable& lhs, const double& rhs); + inline const Variable operator*(const double& lhs, const Variable& rhs); + + // / + inline const Variable operator/(const Variable& lhs, const Variable& rhs); + inline const Variable operator/(const Variable& lhs, const double& rhs); + inline const Variable operator/(const double& lhs, const Variable& rhs); + + // == + inline bool operator==(const Variable& lhs, const Variable& rhs); + inline bool operator==(const Variable& lhs, const double& rhs); + inline bool operator==(const double& lhs, const Variable& rhs); + + // != + inline bool operator!=(const Variable& lhs, const Variable& rhs); + inline bool operator!=(const Variable& lhs, const double& rhs); + inline bool operator!=(const double& lhs, const Variable& rhs); + + // < + inline bool operator<(const Variable& lhs, const Variable& rhs); + inline bool operator<(const Variable& lhs, const double& rhs); + inline bool operator<(const double& lhs, const Variable& rhs); + + // > + inline bool operator>(const Variable& lhs, const Variable& rhs); + inline bool operator>(const Variable& lhs, const double& rhs); + inline bool operator>(const double& lhs, const Variable& rhs); + + // <= + inline bool operator<=(const Variable& lhs, const Variable& rhs); + inline bool operator<=(const Variable& lhs, const double& rhs); + inline bool operator<=(const double& lhs, const Variable& rhs); + + // >= + inline bool operator>=(const Variable& lhs, const Variable& rhs); + inline bool operator>=(const Variable& lhs, const double& rhs); + inline bool operator>=(const double& lhs, const Variable& rhs); + + inline std::ostream& operator<<(std::ostream& os, const Variable& v); + inline Variable& operator<<(Variable& u, const Variable& v); + + inline std::istream& operator>>(std::istream& is, Variable& v); + + +} // namespace Sparse +} // namespace GridKit + +#include "VariableImplementation.hpp" +#include "VariableOperators.hpp" + diff --git a/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp new file mode 100644 index 000000000..f001546a8 --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/VariableImplementation.hpp @@ -0,0 +1,214 @@ +/** + \file VariableImplementation.hpp +*/ + +#pragma once + +namespace GridKit +{ +namespace Sparse +{ + /** + @brief Returns the list of derivatives. + */ + const Variable::DependencyMap& Variable::getDependencies() const + { + assert(dependencies_ != 0); + return *dependencies_; + } + + + /** + @brief Registers a variable as an unknown of the system and + adds a pointer to the global @a x vector. + */ + void Variable::registerVariable(std::vector& x, + const size_t& offset) + { + setVariableNumber(offset); // define global variable number + setFixed(false); // not a constant + + x[offset] = this; + } + + + /** + @brief Adds all dependencies of v to *this. + */ + void Variable::addDependencies(const Variable& v) + { + for (auto& p : *(v.dependencies_)) + (*dependencies_)[p.first] = p.second; + } + + + /** + @brief Multiplies each partial derivative of @a this by @a c. + */ + void Variable::scaleDependencies(double c) + { + for (auto& p : *dependencies_) + (*dependencies_)[p.first] *= c; + } + + + /** + @brief Prints the value and input set of the variable. + */ + void Variable::print(std::ostream& os) const + { + os << value_; + + if (is_fixed_) + { + os << " (fixed)"; + return; + } + + if (variable_number_ != INVALID_VAR_NUMBER) + { + os << " (variable " << variable_number_ << ")"; + return; + } + + if (dependencies_!= NULL && !dependencies_->empty()) + { + os << " dependencies: [ "; + for (auto& p : *dependencies_) + os << "(" << p.first << ", " << p.second << ") "; + os << "]"; + } + } + + + //------------------------------------ + // compound assignment operators + //------------------------------------ + + /** + @brief Compound addition-assignment operator. Right hand + side is a built-in double type. + */ + Variable& Variable::operator+=(const double& rhs) + { + value_ += rhs; + return *this; + } + + /** + @brief Compound addition-assignment operator. Right hand side + is Variable type. + */ + Variable& Variable::operator+=(const Variable& rhs) + { + // compute partial derivatives of *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] += (p.second); + + // compute value of *this + value_ += rhs.value_; + + return *this; + } + + // -= + /** + @brief Compound subtraction-assignment operator. Right hand + side is a built-in double type. + */ + Variable& Variable::operator-=(const double& rhs) + { + value_ -= rhs; + return *this; + } + + /** + @brief Compound subtraction-assignment operator. Right hand + side is a Variable type. + */ + Variable& Variable::operator-=(const Variable& rhs) + { + // compute partial derivatives of *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] -= (p.second); + + // compute value of *this + value_ -= rhs.value_; + + return *this; + } + + // *= + /** + @brief Compound multiplication-assignment operator. Right hand + side is a built-in double type. + */ + Variable& Variable::operator*=(const double& rhs) + { + // Compute derivatives of this + scaleDependencies(rhs); + + // compute value + value_ *= rhs; + + return *this; + } + + /** + @brief Compound multiplication-assignment operator. Right + hand side is a Variable type. + */ + Variable& Variable::operator*=(const Variable& rhs) + { + // derivation by parts of @ *this + scaleDependencies(rhs.value_); + + // compute partial derivatives of rhs and add them to *this + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] += (p.second * value_); + + // compute value of this + value_ *= rhs.value_; + + return *this; + } + + // /= + /** + @brief Compound division-assignment operator. Right hand side + is a built-in double type. + */ + Variable& Variable::operator/=(const double& rhs) + { + double inverseRhs = 1.0/rhs; + + // compute derivatives of @a *this + scaleDependencies(inverseRhs); + + value_ *= inverseRhs; + return *this; + } + + /** + @brief Compound division-assignment operator. Right hand + side is a Variable type. + */ + Variable& Variable::operator/=(const Variable& rhs) + { + double inverseRhs = 1.0/rhs.value_; + double inverseRhsSq = inverseRhs * inverseRhs; + + // derivation by parts of @a *this + scaleDependencies(inverseRhs); + for (auto& p : *(rhs.dependencies_)) + (*dependencies_)[p.first] -= (p.second * value_ * inverseRhsSq); + + // compute value of this + value_ *= inverseRhs; + + return *this; + } + +} // namespace Sparse +} // namespace GridKit + diff --git a/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp new file mode 100644 index 000000000..b97b3e278 --- /dev/null +++ b/src/LinearAlgebra/SparsityPattern/VariableOperators.hpp @@ -0,0 +1,359 @@ +/** + \file VariableOperators.hpp + +*/ +#pragma once + +namespace GridKit +{ +namespace Sparse +{ + //------------------------------------ + // non-member operators and functions + //------------------------------------ + + // unary - + const Variable operator-(const Variable& v) + { + return -1.0*v; + } + + // + + const Variable operator+(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) += rhs; + } + + const Variable operator+(const Variable& lhs, const double& rhs) + { + return Variable(lhs) += rhs; + } + + const Variable operator+(const double& lhs, const Variable& rhs) + { + return Variable(rhs) += lhs; + } + + // - + const Variable operator-(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) -= rhs; + } + + const Variable operator-(const Variable& lhs, const double& rhs) + { + return Variable(lhs) -= rhs; + } + + const Variable operator-(const double& lhs, const Variable& rhs) + { + return Variable(lhs) -= rhs; + } + + // * + const Variable operator*(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) *= rhs; + } + + const Variable operator*(const Variable& lhs, const double& rhs) + { + return Variable(lhs) *= rhs; + } + + const Variable operator*(const double& lhs, const Variable& rhs) + { + return Variable(lhs) *= rhs; + } + + // / + const Variable operator/(const Variable& lhs, const Variable& rhs) + { + return Variable(lhs) /= rhs; + } + + const Variable operator/(const Variable& lhs, const double& rhs) + { + return Variable(lhs) /= rhs; + } + + const Variable operator/(const double& lhs, const Variable& rhs) + { + return Variable(lhs) /= rhs; + } + + // == + bool operator==(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() == rhs.getValue(); + } + + bool operator==(const Variable& lhs, const double& rhs) + { + return lhs.getValue() == rhs; + } + + bool operator==(const double& lhs, const Variable& rhs) + { + return lhs == rhs.getValue(); + } + + // != + bool operator!=(const Variable& lhs, const Variable& rhs) + { + return !(lhs.getValue() == rhs.getValue()); + } + + bool operator!=(const Variable& lhs, const double& rhs) + { + return !(lhs.getValue() == rhs); + } + + bool operator!=(const double& lhs, const Variable& rhs) + { + return !(lhs == rhs.getValue()); + } + + // < + bool operator<(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() < rhs.getValue(); + } + + bool operator<(const Variable& lhs, const double& rhs) + { + return lhs.getValue() < rhs; + } + + bool operator<(const double& lhs, const Variable& rhs) + { + return lhs < rhs.getValue(); + } + + // > + bool operator>(const Variable& lhs, const Variable& rhs) + { + return lhs.getValue() > rhs.getValue(); + } + + bool operator>(const Variable& lhs, const double& rhs) + { + return lhs.getValue() > rhs; + } + + bool operator>(const double& lhs, const Variable& rhs) + { + return lhs > rhs.getValue(); + } + + // <= + bool operator<=(const Variable& lhs, const Variable& rhs) + { + return lhs < rhs || lhs == rhs; + } + + bool operator<=(const Variable& lhs, const double& rhs) + { + return lhs < rhs || lhs == rhs; + } + + bool operator<=(const double& lhs, const Variable& rhs) + { + return lhs < rhs || lhs == rhs; + } + + // >= + bool operator>=(const Variable& lhs, const Variable& rhs) + { + return lhs > rhs || lhs == rhs; + } + + bool operator>=(const Variable& lhs, const double& rhs) + { + return lhs > rhs || lhs == rhs; + } + + bool operator>=(const double& lhs, const Variable& rhs) + { + return lhs > rhs || lhs == rhs; + } + + //------------------------------------ + // non-member operators + //------------------------------------ + + /** + @brief Stream insertion operator for variables. + */ + std::ostream& operator<<(std::ostream& os, const Variable& v) + { + v.print(os); + return os; + } + + /** + @brief Adds all dependencies of a variable, i.e. v << u means + that v depends on u. + + \attention Use only if you know what you are doing! + */ + Variable& operator<<(Variable& u, const Variable& v) + { + u.addDependencies(v); + return u; + } + + /** + @brief Stream extraction operator for variables. + */ + std::istream& operator>>(std::istream& is, Variable& v) + { + return is >> v(); + } + + + //------------------------------------------- + // definitions of cmath functions derivatives + //------------------------------------------- + + + /// Derivative of sine + inline double sin_derivative(double x) + { + return std::cos(x); + } + + /// Derivative of cosine + inline double cos_derivative(double x) + { + return -std::sin(x); + } + + /// Derivative of tangent + inline double tan_derivative(double x) + { + return 1.0/(std::cos(x)*std::cos(x)); + } + + /// Derivative of arc sine + inline double asin_derivative(double x) + { + return std::sqrt(1.0 - x*x); + } + + /// Derivative of arc cosine + inline double acos_derivative(double x) + { + return -std::sqrt(1.0 - x*x); + } + + /// Derivative of arc tangent + inline double atan_derivative(double x) + { + return 1.0/(1.0 + x*x); + } + + /// Derivative of hyperbolic sine + inline double sinh_derivative(double x) + { + return std::cosh(x); + } + + /// Derivative of hyperbolic cosine + inline double cosh_derivative(double x) + { + return std::sinh(x); + } + + /// Derivative of hyperbolic tangent + inline double tanh_derivative(double x) + { + return 1.0/(std::cosh(x)*std::cosh(x)); + } + + /// Derivative of hyperbolic arc sine + inline double asinh_derivative(double x) + { + return std::sqrt(1.0 + x*x); + } + + /// Derivative of hyperbolic arc cosine + inline double acosh_derivative(double x) + { + return std::sqrt(x*x - 1.0); + } + + /// Derivative of hyperbolic arc tangent + inline double atanh_derivative(double x) + { + return 1.0/(1.0 - x*x); + } + + /// Derivative of exponential function. + inline double exp_derivative(double x) + { + return std::exp(x); + } + + /// Derivative of natural logarithm function. + inline double log_derivative(double x) + { + return 1.0/x; + } + + /// Derivative of logarithm to base 10 function: 1/(x*log(10)). + inline double log10_derivative(double x) + { + return 0.4342944819032518/x; + } + + /// Derivative of square root function. + inline double sqrt_derivative(double x) + { + return 0.5/std::sqrt(x); + } + + /// Derivative of absolute value function. + inline double abs_derivative(double x) + { + return x > 0.0 ? 1.0 : -1.0; + } + +} // namespace Sparse +} // namespace GridKit + +// Add all mathematical functions to the namespace std so that, +// for instance, std::sin(x) also works with objects of type Variable. +namespace std +{ + +#define IMPL_FUN_1(FUN,DER) \ + inline GridKit::Sparse::Variable FUN(const GridKit::Sparse::Variable& x) \ + { \ + double val = FUN(x()); \ + double der = DER(x()); \ + GridKit::Sparse::Variable res(x); /* copy derivatives of x*/ \ + res.setValue(val); /* set function value f(x) */ \ + res.scaleDependencies(der); /* compute derivatives of f(x) */ \ + return res; \ + } + + IMPL_FUN_1(sin, GridKit::Sparse::sin_derivative) + IMPL_FUN_1(cos, GridKit::Sparse::cos_derivative) + IMPL_FUN_1(tan, GridKit::Sparse::tan_derivative) + IMPL_FUN_1(asin, GridKit::Sparse::asin_derivative) + IMPL_FUN_1(acos, GridKit::Sparse::acos_derivative) + IMPL_FUN_1(atan, GridKit::Sparse::atan_derivative) + IMPL_FUN_1(sinh, GridKit::Sparse::sinh_derivative) + IMPL_FUN_1(cosh, GridKit::Sparse::cosh_derivative) + IMPL_FUN_1(tanh, GridKit::Sparse::tanh_derivative) + IMPL_FUN_1(exp, GridKit::Sparse::exp_derivative) + IMPL_FUN_1(log, GridKit::Sparse::log_derivative) + IMPL_FUN_1(log10, GridKit::Sparse::log10_derivative) + IMPL_FUN_1(sqrt, GridKit::Sparse::sqrt_derivative) + IMPL_FUN_1(abs, GridKit::Sparse::abs_derivative) + +#undef IMPL_FUN_1 + +} // namespace std + diff --git a/src/Utilities/Testing.hpp b/src/Utilities/Testing.hpp index b5bd9b489..681bb95fd 100644 --- a/src/Utilities/Testing.hpp +++ b/src/Utilities/Testing.hpp @@ -99,6 +99,7 @@ inline bool isEqual(PowerSystemData::GenCostData a, PowerSystemData::GenCostData b, RealT tol = tol_) { + (void) tol; // suppress warning int fail = 0; fail += a.kind != b.kind; fail += a.startup != b.startup; @@ -232,7 +233,7 @@ inline bool isEqual(std::vector a, std::vector b, double tol = tol_) int fail = 0; for (std::size_t i = 0; i < a.size(); i++) { - if (!isEqual(a[i], b[i])) { + if (!isEqual(a[i], b[i], tol)) { fail++; errs() << "[isEqual>]: Got failure with i=" << i << ".\n"; } diff --git a/tests/UnitTests/CMakeLists.txt b/tests/UnitTests/CMakeLists.txt index 970045256..034023832 100644 --- a/tests/UnitTests/CMakeLists.txt +++ b/tests/UnitTests/CMakeLists.txt @@ -1,2 +1,3 @@ # add_subdirectory(PhasorDynamics) +add_subdirectory(SparsityPattern) diff --git a/tests/UnitTests/SparsityPattern/CMakeLists.txt b/tests/UnitTests/SparsityPattern/CMakeLists.txt new file mode 100644 index 000000000..c4c9cc854 --- /dev/null +++ b/tests/UnitTests/SparsityPattern/CMakeLists.txt @@ -0,0 +1,14 @@ +# [[ +# Author(s): +# - Slaven Peles +#]] + + +add_executable(test_sparsity_pattern runSparsityPatternTests.cpp) +target_link_libraries(test_sparsity_pattern GRIDKIT::phasor_dynamics_bus) + + +add_test(NAME SparsityPatternTest COMMAND $) + +install(TARGETS test_sparsity_pattern + RUNTIME DESTINATION bin) diff --git a/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp new file mode 100644 index 000000000..f05dba2ed --- /dev/null +++ b/tests/UnitTests/SparsityPattern/SparsityPatternTests.hpp @@ -0,0 +1,87 @@ +#include +#include + +#include +#include +#include + + +namespace GridKit +{ +namespace Testing +{ + template + class SparsityPatternTests + { + public: + SparsityPatternTests() = default; + ~SparsityPatternTests() = default; + + /// Constructor, allocation, and initialization checks + TestOutcome variable() + { + TestStatus success = true; + + const size_t n = 3; + std::vector x(n), p(n), f(n); + + // decide x, y, and z are variables + for (size_t i = 0; i < n; ++i) + x[i].setVariableNumber(i); + + // ...and sigma, rho, and beta are constant parameters + for (size_t i = 0; i < n; ++i) + p[i].setFixed(true); + + // initialize independent variables + x[0]() = 8.0; x[1]() = 20.0; x[2]() = 2.0/3.0; + + // set constant parameter values + p[0] = 10.0; p[1] = 8.0/3.0; p[2] = 28.0; + + // The residualFunction computes f + residualFunction(f, x, p); + + // Check dependenices of f[0] (depends on x[0] and x[1]) + { + const Sparse::Variable::DependencyMap& dependencies = + (f[0]).getDependencies(); + + success *= (dependencies.size() == 2); + success *= (dependencies.find(0) != dependencies.end()); + success *= (dependencies.find(1) != dependencies.end()); + success *= (dependencies.find(2) == dependencies.end()); + } + + // Check dependencies of f[2] (depends on x[0], x[1], x[2]) + { + const Sparse::Variable::DependencyMap& dependencies = + (f[2]).getDependencies(); + + success *= (dependencies.size() == 3); + success *= (dependencies.find(0) != dependencies.end()); + success *= (dependencies.find(1) != dependencies.end()); + success *= (dependencies.find(2) != dependencies.end()); + } + + return success.report(__func__); + } + + private: + template + void residualFunction(std::vector& f, + const std::vector& x, + const std::vector& p) + { + const T u = x[0]*x[1]; + + f[0] = p[0]*(x[1] - x[0]); // sigma*(y - x) + f[1] = x[0]*(p[1] - x[2]) - x[1]; // x*(rho - z) - y + f[2] = u - p[2]*x[2]; // x*y - beta*z + } + + + }; + +} // namespace Testing +} // namespace GridKit diff --git a/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp new file mode 100644 index 000000000..70273df29 --- /dev/null +++ b/tests/UnitTests/SparsityPattern/runSparsityPatternTests.cpp @@ -0,0 +1,14 @@ +#include "SparsityPatternTests.hpp" + +int main() +{ + using namespace GridKit; + using namespace GridKit::Testing; + + GridKit::Testing::TestingResults result; + GridKit::Testing::SparsityPatternTests test; + + result += test.variable(); + + return result.summary(); +} \ No newline at end of file