Skip to content

Commit 27455f7

Browse files
Add option to suppress algebraic errors in IDA (#464)
1 parent befe03a commit 27455f7

5 files changed

Lines changed: 120 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
- Added off-nominal tap ratio and phase shift support to the PhasorDynamics `Branch` model.
6565
- Added portable Vector class to GridKit
6666
- Added support for running IDA with fixed time steps
67+
- Added IDA option to suppress algebraic variables in local error tests.
6768

6869
## v0.1
6970

GridKit/Solver/Dynamic/Ida.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ namespace AnalysisManager
9292
retval = IDASetId(solver_, tag_);
9393
checkOutput(retval, "IDASetId");
9494

95-
setIDAOptions(solver_, time_step_, rel_tol_, abs_tol_override_, max_steps_);
95+
setIDAOptions(solver_, time_step_, rel_tol_, abs_tol_override_, max_steps_, suppress_alg_);
9696

9797
// Set up linear solver
9898
return this->configureLinearSolver();
@@ -535,7 +535,12 @@ namespace AnalysisManager
535535
retval = IDAInitB(solver_, backwardID_, this->adjointResidual, tf, yyB_, ypB_);
536536
checkOutput(retval, "IDAInitB");
537537

538-
setIDAOptions(IDAGetAdjIDABmem(solver_, backwardID_), backward_time_step_, backward_rel_tol_, backward_abs_tol_override_, backward_max_steps_);
538+
setIDAOptions(IDAGetAdjIDABmem(solver_, backwardID_),
539+
backward_time_step_,
540+
backward_rel_tol_,
541+
backward_abs_tol_override_,
542+
backward_max_steps_,
543+
backward_suppress_alg_);
539544

540545
retval = IDASetUserDataB(solver_, backwardID_, model_);
541546
checkOutput(retval, "IDASetUserDataB");
@@ -1168,6 +1173,35 @@ namespace AnalysisManager
11681173
backward_quadrature_abs_tol_override_ = abs_tol_override;
11691174
}
11701175

1176+
/**
1177+
* @brief Set whether IDA suppresses local error tests on algebraic variables
1178+
*
1179+
* @param suppress If true, algebraic variables are excluded from IDA's
1180+
* local error test
1181+
* @tparam ScalarT Scalar data type
1182+
* @tparam IdxT Index data type
1183+
*/
1184+
template <class ScalarT, typename IdxT>
1185+
void Ida<ScalarT, IdxT>::setSuppressAlgebraicErrors(bool suppress)
1186+
{
1187+
suppress_alg_ = suppress;
1188+
}
1189+
1190+
/**
1191+
* @brief Set whether IDA suppresses local error tests on algebraic
1192+
* variables for the backward simulation
1193+
*
1194+
* @param suppress If true, algebraic variables are excluded from IDA's
1195+
* local error test
1196+
* @tparam ScalarT Scalar data type
1197+
* @tparam IdxT Index data type
1198+
*/
1199+
template <class ScalarT, typename IdxT>
1200+
void Ida<ScalarT, IdxT>::setBackwardSuppressAlgebraicErrors(bool suppress)
1201+
{
1202+
backward_suppress_alg_ = suppress;
1203+
}
1204+
11711205
/**
11721206
* @brief Set the maximum number of steps
11731207
*
@@ -1204,6 +1238,8 @@ namespace AnalysisManager
12041238
* absolute tolerance for the nonlinear solver rather than the
12051239
* model's default absolute tolerance
12061240
* @param max_steps The maximum number of steps
1241+
* @param suppress_alg If true, algebraic variables are excluded from IDA's
1242+
* local error test
12071243
* @tparam ScalarT Scalar data type
12081244
* @tparam IdxT Index data type
12091245
*/
@@ -1212,7 +1248,8 @@ namespace AnalysisManager
12121248
ScalarT time_step,
12131249
ScalarT rel_tol,
12141250
ScalarT abs_tol_override,
1215-
IdxT max_steps)
1251+
IdxT max_steps,
1252+
bool suppress_alg)
12161253
{
12171254
int retval = 0;
12181255
retval = IDASetMinStep(mem, time_step);
@@ -1221,6 +1258,8 @@ namespace AnalysisManager
12211258
checkOutput(retval, "IDASetMaxStep");
12221259
retval = IDASetMaxNumSteps(mem, static_cast<long int>(max_steps));
12231260
checkOutput(retval, "IDASetMaxNumSteps");
1261+
retval = IDASetSuppressAlg(mem, suppress_alg ? SUNTRUE : SUNFALSE);
1262+
checkOutput(retval, "IDASetSuppressAlg");
12241263

12251264
if (time_step == 0)
12261265
{

GridKit/Solver/Dynamic/Ida.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ namespace AnalysisManager
140140
ScalarT abs_tol_override = 0);
141141
void setBackwardQuadratureTolerance(ScalarT rel_tol,
142142
ScalarT abs_tol_override = 0);
143+
void setSuppressAlgebraicErrors(bool suppress);
144+
void setBackwardSuppressAlgebraicErrors(bool suppress);
143145
void setMaxSteps(IdxT maxSteps) override;
144146
void setBackwardMaxSteps(IdxT maxSteps);
145147

@@ -217,11 +219,13 @@ namespace AnalysisManager
217219
RealT rel_tol_{DEFAULT_REL_TOL};
218220
RealT abs_tol_override_{};
219221
IdxT max_steps_{};
222+
bool suppress_alg_{false};
220223

221224
RealT backward_time_step_{};
222225
RealT backward_rel_tol_{DEFAULT_REL_TOL};
223226
RealT backward_abs_tol_override_{};
224227
IdxT backward_max_steps_{};
228+
bool backward_suppress_alg_{false};
225229

226230
RealT quadrature_rel_tol_{0.1 * DEFAULT_REL_TOL};
227231
RealT quadrature_abs_tol_override_{};
@@ -243,7 +247,8 @@ namespace AnalysisManager
243247
ScalarT time_step,
244248
ScalarT rel_tol,
245249
ScalarT abs_tol_override,
246-
IdxT max_steps);
250+
IdxT max_steps,
251+
bool suppress_alg);
247252
void setTolerance(void* mem,
248253
ScalarT rel_tol,
249254
ScalarT abs_tol_override,

tests/UnitTests/Solver/Dynamic/IdaTests.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <cmath>
2+
13
#include <GridKit/Model/Evaluator.hpp>
24
#include <GridKit/Solver/Dynamic/Ida.hpp>
35
#include <GridKit/Testing/TestHelpers.hpp>
@@ -272,6 +274,46 @@ namespace GridKit
272274
std::vector<ScalarT> param_up_;
273275
std::vector<ScalarT> param_lo_;
274276
};
277+
278+
template <class ScalarT, typename IdxT>
279+
class AlgebraicErrorControlEvaluator : public NullEvaluator<ScalarT, IdxT>
280+
{
281+
public:
282+
using RealT = typename NullEvaluator<ScalarT, IdxT>::RealT;
283+
284+
int initialize() override
285+
{
286+
this->y_ = {0, 0};
287+
this->yp_ = {0, 0};
288+
this->tag_ = {true, false};
289+
this->abs_tol_ = {0, 0};
290+
this->f_ = {0, 0};
291+
this->g_ = {0};
292+
t_ = 0;
293+
return 0;
294+
}
295+
296+
IdxT size() override
297+
{
298+
return 2;
299+
}
300+
301+
int evaluateResidual() override
302+
{
303+
static constexpr RealT OMEGA = 100.0;
304+
this->f_[0] = this->yp_[0];
305+
this->f_[1] = this->y_[1] - std::sin(OMEGA * t_);
306+
return 0;
307+
}
308+
309+
void updateTime(RealT t, [[maybe_unused]] RealT a) override
310+
{
311+
t_ = t;
312+
}
313+
314+
private:
315+
RealT t_{};
316+
};
275317
} // namespace Model
276318

277319
namespace Testing
@@ -324,6 +366,34 @@ namespace GridKit
324366

325367
return success.report(__func__);
326368
}
369+
370+
TestOutcome suppressAlgebraicErrors()
371+
{
372+
TestStatus success = true;
373+
374+
const auto countSteps = [](bool suppress_alg)
375+
{
376+
Model::AlgebraicErrorControlEvaluator<ScalarT, IdxT> model;
377+
378+
Ida<ScalarT, IdxT> ida(&model);
379+
ida.setSuppressAlgebraicErrors(suppress_alg);
380+
ida.setTolerance(1.0e-6);
381+
ida.setMaxSteps(10000);
382+
ida.configureSimulation();
383+
384+
ida.initializeSimulation(0.0, false);
385+
ida.runSimulation(1.0);
386+
387+
return ida.getStats().num_steps_;
388+
};
389+
390+
const auto unsuppressed_steps = countSteps(false);
391+
const auto suppressed_steps = countSteps(true);
392+
393+
success *= (suppressed_steps < unsuppressed_steps);
394+
395+
return success.report(__func__);
396+
}
327397
};
328398
} // namespace Testing
329399
} // namespace GridKit

tests/UnitTests/Solver/Dynamic/runIdaTests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int main()
1010

1111
result += test.callback();
1212
result += test.fixedStep();
13+
result += test.suppressAlgebraicErrors();
1314

1415
return result.summary();
1516
}

0 commit comments

Comments
 (0)