Program Listing for File backwardproblem.h
↰ Return to documentation for file (include/amici/backwardproblem.h)
#ifndef AMICI_BACKWARDPROBLEM_H
#define AMICI_BACKWARDPROBLEM_H
#include "amici/defines.h"
#include "amici/forwardproblem.h"
#include "amici/vector.h"
#include <optional>
#include <vector>
namespace amici {
class ExpData;
class Solver;
class Model;
class ForwardProblem;
class SteadystateProblem;
struct BwdSimWorkspace {
BwdSimWorkspace(
gsl::not_null<Model*> model, gsl::not_null<Solver const*> solver
);
Model* model_;
AmiVector xB_;
AmiVector dxB_;
AmiVector xQB_;
std::vector<int> nroots_;
std::vector<Discontinuity> discs_;
int which = 0;
};
class EventHandlingBwdSimulator {
public:
EventHandlingBwdSimulator(
gsl::not_null<Model*> model, gsl::not_null<Solver const*> solver,
gsl::not_null<BwdSimWorkspace*> ws
)
: model_(model)
, solver_(solver)
, ws_(ws) {}
void
run(realtype t_start, realtype t_end, realtype it,
std::vector<realtype> const& timepoints,
std::vector<realtype> const* dJydx, std::vector<realtype> const* dJzdx);
private:
void
handleEventB(Discontinuity const& disc, std::vector<realtype> const* dJzdx);
void handleDataPointB(int it, std::vector<realtype> const* dJydx);
realtype getTnext(int it);
Model* model_;
Solver const* solver_;
gsl::not_null<BwdSimWorkspace*> ws_;
realtype t_{0};
};
class SteadyStateBackwardProblem {
public:
SteadyStateBackwardProblem(
Solver const& solver, Model& model, SolutionState& final_state,
gsl::not_null<BwdSimWorkspace*> ws
);
void run(realtype t0);
[[nodiscard]] double getCPUTimeB() const { return cpu_timeB_; }
[[nodiscard]] int getNumStepsB() const { return numstepsB_; }
[[nodiscard]] AmiVector const& getAdjointState() const;
[[nodiscard]] AmiVector const& getAdjointQuadrature() const;
[[nodiscard]] bool hasQuadrature() const { return has_quadrature_; }
private:
void run_simulation(Solver const& solver);
void compute_steady_state_quadrature(realtype t0);
void compute_quadrature_by_lin_solve();
void compute_quadrature_by_simulation(realtype t0);
double cpu_timeB_{0.0};
bool has_quadrature_{false};
int numstepsB_{0};
AmiVector xQ_;
SolutionState& final_state_;
NewtonSolver newton_solver_;
bool newton_step_conv_{false};
Model* model_{nullptr};
Solver const* solver_{nullptr};
BwdSimWorkspace* ws_{nullptr};
};
class BackwardProblem {
public:
explicit BackwardProblem(ForwardProblem& fwd);
void workBackwardProblem();
[[nodiscard]] AmiVector const& getAdjointStatePrePreeq() const {
return xB_pre_preeq_;
}
[[nodiscard]] AmiVector const& getAdjointQuadraturePrePreeq() const {
return xQB_pre_preeq_;
}
[[nodiscard]] AmiVector const& getAdjointState() const { return ws_.xB_; }
[[nodiscard]] AmiVector const& getAdjointQuadrature() const {
return ws_.xQB_;
}
[[nodiscard]] SteadyStateBackwardProblem const*
getPostequilibrationBwdProblem() const {
if (posteq_problem_bwd_.has_value())
return &*posteq_problem_bwd_;
return nullptr;
}
[[nodiscard]] SteadyStateBackwardProblem const*
getPreequilibrationBwdProblem() const {
if (preeq_problem_bwd_.has_value())
return &*preeq_problem_bwd_;
return nullptr;
}
private:
void handlePostequilibration();
Model* model_;
Solver* solver_;
ExpData const* edata_;
realtype t_;
std::vector<Discontinuity> discs_main_;
std::vector<realtype> dJydx_;
std::vector<realtype> const dJzdx_;
SteadystateProblem* preeq_problem_;
SteadystateProblem* posteq_problem_;
PeriodResult presim_result;
BwdSimWorkspace ws_;
EventHandlingBwdSimulator simulator_;
std::optional<SteadyStateBackwardProblem> preeq_problem_bwd_;
std::optional<SteadyStateBackwardProblem> posteq_problem_bwd_;
AmiVector xB_pre_preeq_;
AmiVector xQB_pre_preeq_;
};
} // namespace amici
#endif // AMICI_BACKWARDPROBLEM_H