menu

Working with ODEs

To learn how to use ODEs, see this tutorial. Here's is a brief overview of the steps discussed there:

ODE setup

// Define ODEs with basic resource dynamics
let resource_dynamics = function (u, k) {
return function (x, y) {
let external = y[0] // The first variable (y[0]) is the external resource concentration, which is taken up with rate u
let internal = y[1] // The second variable (y[1]) is the internal resource concentration, which is used by the cells to divide
return [-u * external, u * external - k * internal]
}
}
// Configuration object with initial states, parameters, and diffusion rates
let ode_config = {
ode_name: "resources",
init_states: [1, 0], // Initial values of external and internal resources
parameters: [0.0, 0.0], // u and k are set to 0.0 by default, as we will make it dependent on cell presence!
diffusion_rates: [0.2, 0.0] // resources diffuse through exteral environment, but internal resources stay inside cells
}

Attach the ODE to the grid points

sim.model.attachODE(resource_dynamics, ode_config)

Solving the ODEs

Solving the ODEs is then done in the nextState function, by adding:
this.grid[i][j].resources.solveTimestep(0.1) // (0.1=delta_time)

Manipulate the parameters at run time

You may want to change the state and parameters of the ODE based on certain events. For example, if the individual responsible for the uptake dies, the amount of internal resources should be 0.00, and the rate of uptake should be 0.00:
this.grid[i][j].alive = 0
this.grid[i][j].resources.state[1] = 0.00 // Remove internal conc
this.grid[i][j].resources.pars = [influx, 0.00, upkeep] // No more cell here, so no uptake