Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Version 2.1.1 development #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 11, 2025
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# dae-cpp

![tests](https://github.com/dae-cpp/dae-cpp/actions/workflows/cmake-multi-platform.yml/badge.svg)
![version](https://img.shields.io/badge/version-2.1.0-blue)
![version](https://img.shields.io/badge/version-2.1.1-blue)
[![Static Badge](https://img.shields.io/badge/Documentation-8A2BE2?logo=githubpages&logoColor=fff&style=flat)](https://dae-cpp.github.io/)

**A simple but powerful header-only C++ solver for [systems of Differential-Algebraic Equations](https://en.wikipedia.org/wiki/Differential-algebraic_system_of_equations) (DAE).**
Expand All @@ -20,6 +20,7 @@ to be solved in the interval $`t \in [0, t_\mathrm{end}]`$ with the initial cond

- Header only, no pre-compilation required.
- Uses [automatic](https://en.wikipedia.org/wiki/Automatic_differentiation) (algorithmic, exact) differentiation ([autodiff](https://autodiff.github.io/) package) to compute the Jacobian matrix, if it is not provided by the user.
- The user can provide analytically derived Jacobian or the Jacobian matrix shape (positions of non-zero elements) to significantly speed up the computation for big systems.
- Fourth-order variable-step implicit BDF time integrator that preserves accuracy even when the time step rapidly changes.
- A very flexible and customizable variable time stepping algorithm based on the solution stability and variability.
- Mass matrix can be non-static (can depend on time) and it can be singular (contain empty rows).
Expand Down
10 changes: 6 additions & 4 deletions dae-cpp/assert-custom.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ namespace daecpp_namespace_name
* Example:
* ERROR("v = " << v);
*/
#define ERROR(msg) \
std::cerr << "\nERROR: " << msg << "\nThis error is fatal." << std::endl; \
exit(-1);
#define ERROR(msg) \
{ \
std::cerr << "\nERROR: " << msg << "\nThis error is fatal." << std::endl; \
exit(-1); \
}

/*
* WARNING(warning message)
Expand Down Expand Up @@ -62,7 +64,7 @@ namespace daecpp_namespace_name
/*
* PRINT(condition, message)
*
* Prints a message if condition (e.g., verbosity level) is true.
* Prints a message if condition (e.g., verbosity level) is true and flushes the output.
*
* Example:
* NOTE(verbosity > 1, "v = " << v);
Expand Down
4 changes: 2 additions & 2 deletions dae-cpp/jacobian-matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ class JacobianCompare
std::vector<core::MatrixDiff> J_diff;

// Perform comparison element-by-element
for (int_type j = 0; j < size; ++j)
for (int_type i = 0; i < size; ++i)
{
for (int_type i = 0; i < size; ++i)
for (int_type j = 0; j < size; ++j)
{
if (std::abs(Jd_auto(i, j) - Jd_user(i, j)) > DAECPP_SPARSE_MATRIX_ELEMENT_TOLERANCE)
{
Expand Down
4 changes: 4 additions & 0 deletions dae-cpp/solver-options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ struct SolverOptions
// Default value is 3.
unsigned int max_Newton_failed_attempts{3};

// If `true`, the solver will try to recover from the linear solver failure by rolling back and decreasing the time step.
// Default value is `true`.
bool recover_from_linsolver_failure{true};

// Time step amplification threshold delta (0 by default). Can be negative or positive integer number.
// The solver increases the time step if the number of successful Newton iterations per time step is less than the threshold.
// Example: If the solver increases the time step too often (too fast), decrease the time step amplification threshold by
Expand Down
19 changes: 15 additions & 4 deletions dae-cpp/solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,14 +536,19 @@ inline exit_code::status solve(Mass mass, RHS rhs, Jacobian jac, Manager mgr, co

linsolver.compute(Jb);

c.n_fact_calls++;

if (linsolver.info() != Eigen::Success)
{
PRINT(opt.verbosity >= 2, " <- decomposition failed");
if(opt.recover_from_linsolver_failure)
{
is_diverged = true;
break;
}
error_msg = exit_code::linsolver_failed_decomposition;
goto result; // Abort all loops and go straight to the results
}

c.n_fact_calls++;
}

// Solve linear system Jb dx = b
Expand All @@ -552,15 +557,20 @@ inline exit_code::status solve(Mass mass, RHS rhs, Jacobian jac, Manager mgr, co

dx = linsolver.solve(b);

c.n_lin_calls++;

if (linsolver.info() != Eigen::Success)
{
PRINT(opt.verbosity >= 2, " <- linear solver failed");
if(opt.recover_from_linsolver_failure)
{
is_diverged = true;
break;
}
error_msg = exit_code::linsolver_failed_solving;
goto result; // Abort all loops and go straight to the results
}

c.n_lin_calls++;

if (is_fact_enabled)
{
print_char(opt.verbosity >= 2, '#');
Expand Down Expand Up @@ -633,6 +643,7 @@ inline exit_code::status solve(Mass mass, RHS rhs, Jacobian jac, Manager mgr, co
state.t = state.t_prev;
n_steps--;
dt /= opt.dt_decrease_factor;
xk = state.x[0];
if (dt < opt.dt_min)
{
PRINT(opt.verbosity >= 1, "The time step was reduced to `t_min` but the scheme failed to converge.");
Expand Down
2 changes: 1 addition & 1 deletion dae-cpp/timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Usage example:
*
* double time = 0.0;
* double time{};
* {
* Timer timer(&time);
* << TASK >>
Expand Down
5 changes: 4 additions & 1 deletion dae-cpp/typedefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ typedef float float_type;
typedef double float_type;
#endif

// Floating point dual number for automatic differentiation
// Floating point dual number for automatic differentiation (DEPRECATED: use state_value)
typedef autodiff::real1st dual_type;

// Floating point dual number for automatic differentiation
typedef autodiff::real1st state_value;

namespace core
{

Expand Down
2 changes: 1 addition & 1 deletion dae-cpp/vector-function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class VectorFunctionElements
* I.e., it returns the i-th element of the vector function.
* This function is pure virtual and must be overriden.
*/
virtual dual_type equations(const state_type &x, const double t, const int_type i) const = 0;
virtual state_value equations(const state_type &x, const double t, const int_type i) const = 0;

virtual ~VectorFunctionElements() {}
};
Expand Down
2 changes: 1 addition & 1 deletion examples/flame_propagation/flame_propagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct MyRHS
*/
void operator()(state_type &f, const state_type &x, const double t)
{
dual_type y = x[0]; // Note `dual_type` (not `double`) because the solver will automatically differentiate `f` w.r.t. `y`
state_value y = x[0]; // Note `state_value` (not `double`) because the solver will automatically differentiate `f` w.r.t. `y`
f[0] = y * y - y * y * y;
}
};
Expand Down
10 changes: 5 additions & 5 deletions examples/jacobian_compare/jacobian_compare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ struct MyRHS
*/
void operator()(state_type &f, const state_type &x, const double t)
{
// `dual_type` for automatic differentiation
dual_type u = x[0];
dual_type v = x[1];
dual_type w = x[2];
dual_type z = x[3];
// `state_value` for automatic differentiation
state_value u = x[0];
state_value v = x[1];
state_value w = x[2];
state_value z = x[3];

f[0] = z * 0.5;
f[1] = u * u + v * v + w * w;
Expand Down
14 changes: 7 additions & 7 deletions examples/jacobian_shape/jacobian_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ class MyRHS : public VectorFunctionElements
* RHS for the ion concentration P = dFlux/dx:
* dP/dt = d/dx(dP/dx + P * dPhi/dx)
*/
dual_type eq1(const state_type &x, const double t, const int_type i_global) const
state_value eq1(const state_type &x, const double t, const int_type i_global) const
{
const dual_type *P = x.data();
const dual_type *Phi = x.data() + p.N;
const state_value *P = x.data();
const state_value *Phi = x.data() + p.N;

const int_type i = i_global;

Expand All @@ -123,10 +123,10 @@ class MyRHS : public VectorFunctionElements
* RHS for the potential Phi:
* d^2(Phi)/dx^2 - (1 - P)/lambda^2 = 0
*/
dual_type eq2(const state_type &x, const double t, const int_type i_global) const
state_value eq2(const state_type &x, const double t, const int_type i_global) const
{
const dual_type *P = x.data();
const dual_type *Phi = x.data() + p.N;
const state_value *P = x.data();
const state_value *Phi = x.data() + p.N;

const int_type i = i_global - p.N;

Expand All @@ -145,7 +145,7 @@ class MyRHS : public VectorFunctionElements
* All equations combined.
* This function returns the i-th component of the vector function.
*/
dual_type equations(const state_type &x, const double t, const int_type i) const
state_value equations(const state_type &x, const double t, const int_type i) const
{
if (i < p.N)
return eq1(x, t, i);
Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration-flame_propagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct MyRHS
{
void operator()(state_type &f, const state_type &x, const double t)
{
dual_type y = x[0];
state_value y = x[0];
f[0] = y * y - y * y * y;
}
};
Expand Down
14 changes: 7 additions & 7 deletions tests/test_integration-jacobian_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ class MyRHS : public VectorFunctionElements
* RHS for the ion concentration P = dFlux/dx:
* dP/dt = d/dx(dP/dx + P * dPhi/dx)
*/
dual_type eq1(const state_type &x, const double t, const int_type i_global) const
state_value eq1(const state_type &x, const double t, const int_type i_global) const
{
const dual_type *P = x.data();
const dual_type *Phi = x.data() + p.N;
const state_value *P = x.data();
const state_value *Phi = x.data() + p.N;

const int_type i = i_global;

Expand All @@ -81,10 +81,10 @@ class MyRHS : public VectorFunctionElements
* RHS for the potential Phi:
* d^2(Phi)/dx^2 - (1 - P)/lambda^2 = 0
*/
dual_type eq2(const state_type &x, const double t, const int_type i_global) const
state_value eq2(const state_type &x, const double t, const int_type i_global) const
{
const dual_type *P = x.data();
const dual_type *Phi = x.data() + p.N;
const state_value *P = x.data();
const state_value *Phi = x.data() + p.N;

const int_type i = i_global - p.N;

Expand All @@ -103,7 +103,7 @@ class MyRHS : public VectorFunctionElements
* All equations combined.
* This function returns the i-th component of the vector function.
*/
dual_type equations(const state_type &x, const double t, const int_type i) const
state_value equations(const state_type &x, const double t, const int_type i) const
{
if (i < p.N)
return eq1(x, t, i);
Expand Down
22 changes: 11 additions & 11 deletions tests/test_jacobian-compare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ struct MyRHS
{
void operator()(state_type &f, const state_type &x, const double t)
{
// `dual_type` for automatic differentiation
dual_type u = x[0];
dual_type v = x[1];
dual_type w = x[2];
dual_type z = x[3];
// `state_value` for automatic differentiation
state_value u = x[0];
state_value v = x[1];
state_value w = x[2];
state_value z = x[3];

f[0] = z * 0.5;
f[1] = u * u + v * v + w * w;
Expand Down Expand Up @@ -82,13 +82,13 @@ struct MyJacobianGood
class MyRHSShape : public VectorFunctionElements
{
public:
dual_type equations(const state_type &x, const double t, const int_type i) const
state_value equations(const state_type &x, const double t, const int_type i) const
{
// `dual_type` for automatic differentiation
dual_type u = x[0];
dual_type v = x[1];
dual_type w = x[2];
dual_type z = x[3];
// `state_value` for automatic differentiation
state_value u = x[0];
state_value v = x[1];
state_value w = x[2];
state_value z = x[3];

if (i == 0)
return z * 0.5;
Expand Down
2 changes: 1 addition & 1 deletion tests/test_jacobian-shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ using namespace daecpp;

struct TestRHS : VectorFunctionElements
{
dual_type equations(const state_type &x, const double t, const int_type i) const
state_value equations(const state_type &x, const double t, const int_type i) const
{
if (i == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion tests/test_vector-function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ TEST(VectorFunctionElements, Definition)
{
struct TestVectorFunction : VectorFunctionElements
{
dual_type equations(const state_type &x, const double t, const int_type i) const
state_value equations(const state_type &x, const double t, const int_type i) const
{
ASSERT(x.size() == 2, "Incorrect size of x: " << x.size());

Expand Down
Loading