tutorials:ode-framework
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
tutorials:ode-framework [2025/07/25 12:34] – created Tim | tutorials:ode-framework [2025/07/25 14:13] (current) – Tim | ||
---|---|---|---|
Line 19: | Line 19: | ||
From a numerical point of view this corresponds to simple explicit Euler integration (with step size of h, often just set to 1). This should be avoided in practice, since the results from an Euler numerical integration can differ substantially from the exact analytical solution, depending on the type of ODE and the integration step size chosen. Euler integration also suffers from stability problems if the step size chosen is too large. | From a numerical point of view this corresponds to simple explicit Euler integration (with step size of h, often just set to 1). This should be avoided in practice, since the results from an Euler numerical integration can differ substantially from the exact analytical solution, depending on the type of ODE and the integration step size chosen. Euler integration also suffers from stability problems if the step size chosen is too large. | ||
- | ===== Advanced numerical methods | + | ==== Advanced numerical methods |
A very commonly used method to solve [[https:// | A very commonly used method to solve [[https:// | ||
Line 45: | Line 45: | ||
are the values of the first derivation for different combinations of time and state. | are the values of the first derivation for different combinations of time and state. | ||
- | ===== Using the ODE framework | + | ==== Using the ODE framework |
The interface between the problem to be solved and an ODE integrator like RK4 is given by the initial state and time and the rate function $f(t,y)$. Specification of ODEs from within an RGG must occur inside a function void '' | The interface between the problem to be solved and an ODE integrator like RK4 is given by the initial state and time and the rate function $f(t,y)$. Specification of ODEs from within an RGG must occur inside a function void '' | ||
Line 56: | Line 56: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | Note that the integration step size is not given explicitly, as choosing it is up to the integrator. While the two ways of defining the diffusion of the carbon assimilates look very similar (which was an important design goal), both of them are handled very differently internally. | ||
+ | |||
+ | ==== The getRate() function ==== | ||
+ | |||
+ | All ODEs must be specified by the user inside a function '' | ||
+ | |||
+ | ===== Simple example | ||
+ | |||
+ | A simple but complete example as RGG program is this: | ||
+ | |||
+ | < | ||
+ | module A(double len); | ||
+ | protected void init () | ||
+ | [ | ||
+ | Axiom ==> A(1); | ||
+ | ] | ||
+ | public void run () | ||
+ | { | ||
+ | integrate(10); | ||
+ | println((* a:A *)[len] + " (" + a + " | ||
+ | } | ||
+ | protected void getRate() | ||
+ | [ | ||
+ | a:A ::> a[len] :'= 1.23; | ||
+ | ] | ||
+ | </ | ||
+ | |||
+ | Here, a module A is created with an initial value of its attribute len of 1. Integration is performed over 10 time units. Afterwards the resulting value of the attribute is printed. The rate function $f(t,y)$ is given by the '' | ||
+ | |||
+ | ===== Monitor functions ===== | ||
+ | |||
+ | A common situation that might appear is to stop an integration conditionally, | ||
+ | |||
+ | < | ||
+ | module A(double len); | ||
+ | protected void init () | ||
+ | [ | ||
+ | Axiom ==> A(1); | ||
+ | ] | ||
+ | public void run () | ||
+ | { | ||
+ | [ a:A ::> monitor(void=> | ||
+ | integrate(10); | ||
+ | println((* a:A *)[len] + " (" + a + " | ||
+ | } | ||
+ | protected void getRate() | ||
+ | [ | ||
+ | a:A ::> a[len] :'= 1.23; | ||
+ | ] | ||
+ | </ | ||
+ | |||
+ | ===== monitorPeriodic ===== | ||
+ | |||
+ | Trigger an event in regular intervals and call the event handler. The event handler must not modify the graph. | ||
+ | |||
+ | This allows to keep track of the changes for example: | ||
+ | < | ||
+ | import static java.lang.Math.*; | ||
+ | DatasetRef data = new DatasetRef(" | ||
+ | const double PERIOD = 1.0; | ||
+ | double t; | ||
+ | double x; | ||
+ | protected void init () | ||
+ | { | ||
+ | data.clear().setColumnKey(0, | ||
+ | chart(data, XY_PLOT); | ||
+ | t = 0; | ||
+ | x = 1; | ||
+ | data.addRow().setX(0, | ||
+ | } | ||
+ | public void run () | ||
+ | { | ||
+ | monitorPeriodic(1, | ||
+ | public void run() { data.addRow().setX(0, | ||
+ | }); | ||
+ | |||
+ | integrate(10); | ||
+ | } | ||
+ | protected void getRate() | ||
+ | { | ||
+ | t :'= 1; | ||
+ | x :'= 0.1 * x; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ |
tutorials/ode-framework.1753439645.txt.gz · Last modified: 2025/07/25 12:34 by Tim