Implement a generic solver of ODE on a graph. More...
Classes | |
class | Solver |
Implement a set of solvers for ODE on a graph. More... | |
Enumerations | |
enum | SolvingMethod { Euler, AdaptiveEuler, Fixedpoint, Midpoint, RungeKutta, AdaptiveRungeKutta, AdaptiveCrankNicholson } |
Available solving methods. More... | |
enum | ToleranceType { MAX_COMPONENT, MEAN_COMPONENT } |
Type of the tolerances. More... | |
Functions | |
std::ostream & | operator<< (std::ostream &s, const ToleranceType &m) |
std::ostream & | operator<< (std::ostream &s, const SolvingMethod &m) |
QTextStream & | operator<< (QTextStream &s, const SolvingMethod &m) |
std::istream & | operator>> (std::istream &s, ToleranceType &m) |
std::istream & | operator>> (std::istream &s, SolvingMethod &m) |
QTextStream & | operator>> (QTextStream &s, SolvingMethod &m) |
Implement a generic solver of ODE on a graph.
This module implements a set of ODE solvers on a graph, from forward Euler to Cranck-Nicholson. It assumes a symmetric graph (i.e. for each vertex v1
and v2
, if there is an edge from v1
to v2
, there must be an edge from v2
to v1
).
This module is used by constructing a solver::Solver object which holds the parameters for solving and the time stepping.
Most solvers requires an internal structure to be placed in the content of your vertexes and edge.
For example, to solve a 3-components system (i.e. 3 component on each vertex of the graph):
typedef solver::Solver<3> RDSolver; struct VertexContent { // ... RDSolver::VertexInternals interns; }; struct EdgeContent { // ... RDSolver::EdgeInternals interns; }; class MyModel : public Model { public: RDSolver solve; typedef RDSolver::tag_t tag_t; vvgraph S; void step() { solve(S, *this); } };
To use this module, the user needs to define some methods in its model class. Each class accept as argument a tag to differentiate between different solvers used in the same model. If you have different solvers with the same template arguments, then you can add an optional argument to differentiate them:
struct reaction_diffusion_solver {}; struct mass_spring_solver {}; typedef solver::Solver<2,reaction_diffusion_solver> RDSolver; typedef solver::Solver<2,mass_spring_solver> MSSolver; struct VertexContent { // ... RDSolver::VertexInternals rd_interns; MSSolver::VertexInternals ms_interns; }; struct EdgeContent { // ... RDSolver::EdgeInternals rd_interns; MSSolver::EdgeInternals ms_interns; }; class MyModel : public Model { RDSolver rd_solve; typedef RDSolver::tag_t rd_tag_t; MSSolver ms_solve; typeder MSSolver::tag_t ms_tag_t; };
Here are the methods to define in your model:
util::Vector<nb_chemicals,double>& values(const vertex& v, const tag_t& tag);
Returns a reference on the vector containing the values for the different components of the ODE on the vertex v
.
util::Vector<nb_vars,double>& derivatives(const vertex& v, const tag_t& tag);
Returns a reference on the vector containing the derivatives for the different components of the ODE on the vertex v
.
void updateDerivatives(const vertex& v, const tag_t& tag);
Update the time derivatives of the components on the vertex v
. You must not change any data outside the vertex v
. Plus, you should not assume any order in the evaluation of this function. You might even assume all the updateDerivatives may be evaluated in parallel (I hope it will eventually by the case).
Solver::VertexInternals& vertexInternals(const vertex& v, const tag_t& tag);
This method is not used for the forward Euler method. For all other you have to implement it. It means also that your vertex has to contain an instance Solver::VertexInternals
. This method should return a reference on that structure.
Solver::EdgeInternals& edgeInternals(const vertex& src, const vertex& tgt, graph& S, const tag_t& tag);
This method is only used in the Cranck-Nicholson solver, so if you do not intent on using it, you don't need edge internals. Note however that if you let the user choose, you have to implement ALL the methods, even if you never use them. It should return a reference on the edgeInternals structure for the solver.
Available solving methods.
There is stream operator defined to read and write the methods with the exact same name
Definition at line 218 of file solver.h.
00219 { 00221 Euler, 00223 AdaptiveEuler, 00225 Fixedpoint, 00227 Midpoint, 00229 RungeKutta, 00231 AdaptiveRungeKutta, 00233 AdaptiveCrankNicholson 00234 };
Type of the tolerances.
A stream operator define the read/write methods
MAX_COMPONENT |
Extract the maximum value to compute the precision (name: MaxComponent). |
MEAN_COMPONENT |
Extract the mean of the values to compute the precision (name: MeanComponent). |
Definition at line 346 of file solver.h.
00347 { 00349 MAX_COMPONENT, 00351 MEAN_COMPONENT 00352 };