Skip to content

Commit

Permalink
Enable specifying maximum solver step size (#2360)
Browse files Browse the repository at this point in the history
  • Loading branch information
dweindl authored Mar 6, 2024
1 parent dcc81d1 commit ddffa93
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/amici/serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void serialize(Archive& ar, amici::Solver& s, unsigned int const /*version*/) {
ar & s.maxtime_;
ar & s.max_conv_fails_;
ar & s.max_nonlin_iters_;
ar & s.max_step_size_;
}

/**
Expand Down
20 changes: 20 additions & 0 deletions include/amici/solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,18 @@ class Solver {
*/
int getMaxConvFails() const;

/**
* @brief Set the maximum step size
* @param max_step_size maximum step size. `0.0` means no limit.
*/
void setMaxStepSize(realtype max_step_size);

/**
* @brief Get the maximum step size
* @return maximum step size
*/
realtype getMaxStepSize() const;

/**
* @brief Serialize Solver (see boost::serialization::serialize)
* @param ar Archive to serialize to
Expand Down Expand Up @@ -1752,6 +1764,11 @@ class Solver {
*/
virtual void apply_max_conv_fails() const = 0;

/**
* @brief Apply the allowed maximum stepsize to the solver.
*/
virtual void apply_max_step_size() const = 0;

/** state (dimension: nx_solver) */
mutable AmiVector x_{0};

Expand Down Expand Up @@ -1891,6 +1908,9 @@ class Solver {
* step */
int max_conv_fails_{10};

/** Maximum allowed step size */
realtype max_step_size_{0.0};

/** CPU time, forward solve */
mutable realtype cpu_time_{0.0};

Expand Down
2 changes: 2 additions & 0 deletions include/amici/solver_cvodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ class CVodeSolver : public Solver {
void apply_max_nonlin_iters() const override;

void apply_max_conv_fails() const override;

void apply_max_step_size() const override;
};

} // namespace amici
Expand Down
2 changes: 2 additions & 0 deletions include/amici/solver_idas.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ class IDASolver : public Solver {
void apply_max_nonlin_iters() const override;

void apply_max_conv_fails() const override;

void apply_max_step_size() const override;
};

} // namespace amici
Expand Down
11 changes: 11 additions & 0 deletions src/hdf5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,11 @@ void writeSolverSettingsToHDF5(
file.getId(), hdf5Location.c_str(), "maxtime", &dbuffer, 1
);

dbuffer = solver.getMaxStepSize();
H5LTset_attribute_double(
file.getId(), hdf5Location.c_str(), "max_step_size", &dbuffer, 1
);

ibuffer = gsl::narrow<int>(solver.getMaxSteps());
H5LTset_attribute_int(
file.getId(), hdf5Location.c_str(), "maxsteps", &ibuffer, 1
Expand Down Expand Up @@ -1000,6 +1005,12 @@ void readSolverSettingsFromHDF5(
);
}

if (attributeExists(file, datasetPath, "max_step_size")) {
solver.setMaxStepSize(
getDoubleScalarAttribute(file, datasetPath, "max_step_size")
);
}

if (attributeExists(file, datasetPath, "maxsteps")) {
solver.setMaxSteps(getIntScalarAttribute(file, datasetPath, "maxsteps")
);
Expand Down
10 changes: 10 additions & 0 deletions src/solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Solver::Solver(Solver const& other)
, check_sensi_steadystate_conv_(other.check_sensi_steadystate_conv_)
, max_nonlin_iters_(other.max_nonlin_iters_)
, max_conv_fails_(other.max_conv_fails_)
, max_step_size_(other.max_step_size_)
, maxstepsB_(other.maxstepsB_)
, sensi_(other.sensi_) {}

Expand Down Expand Up @@ -195,6 +196,7 @@ void Solver::setup(

apply_max_nonlin_iters();
apply_max_conv_fails();
apply_max_step_size();

cpu_time_ = 0.0;
cpu_timeB_ = 0.0;
Expand Down Expand Up @@ -691,6 +693,14 @@ void Solver::setMaxConvFails(int max_conv_fails) {

int Solver::getMaxConvFails() const { return max_conv_fails_; }

void Solver::setMaxStepSize(realtype max_step_size) {
if (max_step_size < 0)
throw AmiException("max_step_size must be non-negative.");
max_step_size_ = max_step_size;
}

realtype Solver::getMaxStepSize() const { return max_step_size_; }

int Solver::getNewtonMaxSteps() const { return newton_maxsteps_; }

void Solver::setNewtonMaxSteps(int const newton_maxsteps) {
Expand Down
6 changes: 6 additions & 0 deletions src/solver_cvodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ void CVodeSolver::apply_max_conv_fails() const {
throw CvodeException(status, "CVodeSetMaxConvFails");
}

void CVodeSolver::apply_max_step_size() const {
int status = CVodeSetMaxStep(solver_memory_.get(), getMaxStepSize());
if (status != CV_SUCCESS)
throw CvodeException(status, "CVodeSetMaxStep");
}

Solver* CVodeSolver::clone() const { return new CVodeSolver(*this); }

void CVodeSolver::allocateSolver() const {
Expand Down
6 changes: 6 additions & 0 deletions src/solver_idas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ void IDASolver::apply_max_conv_fails() const {
throw IDAException(status, "IDASetMaxConvFails");
}

void IDASolver::apply_max_step_size() const {
int status = IDASetMaxStep(solver_memory_.get(), getMaxStepSize());
if (status != IDA_SUCCESS)
throw IDAException(status, "IDASetMaxStep");
}

Solver* IDASolver::clone() const { return new IDASolver(*this); }

void IDASolver::allocateSolver() const {
Expand Down

0 comments on commit ddffa93

Please sign in to comment.