Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codegen for CVODE #1493

Merged
merged 103 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 101 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
417acac
Add `DerivativeOriginalFunctionBlock` and `DerivativeVisitor`
JCGoran Sep 24, 2024
d33a594
Remove unused functions
JCGoran Sep 24, 2024
b9f08d0
Add test for DerivativeOriginalVisitor
JCGoran Sep 25, 2024
c5dc45e
Fmt
JCGoran Sep 25, 2024
1dadd7a
Fix leak
JCGoran Sep 25, 2024
1125fdf
Remove unused stuff
JCGoran Sep 25, 2024
0267fbd
Update block description
JCGoran Sep 25, 2024
e58070f
Rename DERIVATIVE_ORIGINAL to CVODE
JCGoran Sep 27, 2024
044dfd9
Finish renaming
JCGoran Sep 30, 2024
50f38ce
Add item with Jacobian
JCGoran Sep 30, 2024
bc68701
Merge branch 'master' into jelic/cvode_visitors
JCGoran Sep 30, 2024
f82fe1f
Do not use an int but an enum-wrapped int
JCGoran Sep 30, 2024
bd2fd36
Add support for diffing expressions with indexed vars
JCGoran Sep 30, 2024
b082f0d
Allow diffing implicit functions in `differentiate2c`
JCGoran Sep 30, 2024
edf33a7
Simplify condition
JCGoran Sep 30, 2024
565fa03
Better testing
JCGoran Oct 1, 2024
6bd6aed
Add suggestions from code review
JCGoran Oct 1, 2024
0eba407
Add `stepsize` param to `differentiate2c`
JCGoran Oct 2, 2024
405909e
Merge remote-tracking branch 'origin/master' into jelic/diff_implicit
JCGoran Oct 2, 2024
c1e7fd3
Try Python 3.9 maybe?
JCGoran Oct 2, 2024
0207373
Merge branch 'jelic/diff_indexed' into jelic/cvode_visitors
JCGoran Oct 2, 2024
32d36a8
Merge branch 'jelic/diff_implicit' into jelic/cvode_visitors
JCGoran Oct 2, 2024
4562945
Add codegen
JCGoran Oct 2, 2024
dcf47ab
Spurious change
JCGoran Oct 2, 2024
34371cc
Stop using numpy to please MacOS dual-arch build
JCGoran Oct 2, 2024
f725f05
Isolate symbol-making
JCGoran Oct 2, 2024
6658bf4
Forgot one
JCGoran Oct 2, 2024
f94d7d3
Merge branch 'jelic/diff_implicit' into jelic/cvode_codegen_only
JCGoran Oct 2, 2024
09b4ee7
Merge branch 'jelic/diff_indexed' into jelic/cvode_codegen_only
JCGoran Oct 2, 2024
e0c087c
Leave out KINETIC block for now
JCGoran Oct 2, 2024
2470dff
Add missing import
JCGoran Oct 2, 2024
4e9fb49
Merge remote-tracking branch 'origin/master' into jelic/cvode_visitors
JCGoran Oct 7, 2024
4fde929
Put back Python 3.8 for now
JCGoran Oct 7, 2024
a08df25
Remove remaining occurrences of `DerivativeOriginalVisitor`
JCGoran Oct 7, 2024
9fee9a8
WIP on CONSERVE
JCGoran Oct 8, 2024
d98fcc0
Ignore CONSERVE equations
JCGoran Oct 9, 2024
321cdb3
Add documentation
JCGoran Oct 10, 2024
2984e46
Really delete CONSERVE statements this time
JCGoran Oct 10, 2024
313330b
Add test for CONSERVE statement
JCGoran Oct 10, 2024
03b40e8
Fix variable naming
JCGoran Oct 10, 2024
bc898c9
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 10, 2024
8cd6a39
Put back the right one
JCGoran Oct 10, 2024
d8c86de
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 10, 2024
4c423dd
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 10, 2024
fc4fe9d
I don't need this
JCGoran Oct 10, 2024
bf3b0e6
Fixups
JCGoran Oct 10, 2024
836ec74
Update docstring
JCGoran Oct 10, 2024
9f6b751
Fix typo
JCGoran Oct 10, 2024
1348ab9
Update docstring
JCGoran Oct 10, 2024
ee0247f
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 10, 2024
2ae9db2
Remove unused code
JCGoran Oct 10, 2024
96b1bb6
Merge branch 'master' into jelic/cvode_visitors
JCGoran Oct 14, 2024
9ffd6c7
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 14, 2024
ee9c187
Add option for diffing IndexedName
JCGoran Oct 14, 2024
54a480e
Refactor
JCGoran Oct 14, 2024
32aa0cb
Merge branch 'master' into jelic/cvode_visitors
JCGoran Oct 14, 2024
cefc159
Enable sympy if NEURON codegen
JCGoran Oct 14, 2024
703e83c
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 14, 2024
a3e1c6c
Mark constructors as explicit
JCGoran Oct 14, 2024
d9a86c0
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 14, 2024
7177fb6
Merge branch 'master' into jelic/cvode_visitors
JCGoran Oct 15, 2024
659b018
Update tests
JCGoran Oct 15, 2024
bd376c3
Remove code duplication
JCGoran Oct 15, 2024
a60577b
Remove unused class field
JCGoran Oct 15, 2024
ceddb75
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 16, 2024
221c612
Merge remote-tracking branch 'origin/jelic/cvode_codegen_only' into j…
JCGoran Oct 16, 2024
8bc7d18
Only enable sympy if DERIVATIVE block exists
JCGoran Oct 16, 2024
ca76a54
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 16, 2024
40cb10b
Rename CVODE subblocks with more apt names
JCGoran Oct 16, 2024
bbabdb3
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 16, 2024
b29c277
Rename function calls
JCGoran Oct 16, 2024
9b58feb
`nonstiff` -> `non_stiff`
JCGoran Oct 16, 2024
d1a58e9
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 16, 2024
052a8b7
Fix typo in codegen
JCGoran Oct 21, 2024
6bee9e0
Fix issues with wrong # of ODEs
JCGoran Oct 21, 2024
af1fbf0
Revert back part of master for compatibility
JCGoran Oct 21, 2024
a6ea5ab
Get # of ODEs to solve
JCGoran Oct 21, 2024
09c58c3
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 21, 2024
494dbe7
Reorder tests
JCGoran Oct 21, 2024
5d94f7a
der_block(s) -> derivative_block(s)
JCGoran Oct 21, 2024
bf9db7a
get_name_map -> get_indexed_variables
JCGoran Oct 21, 2024
fd0c619
Add check for multiple DERIVATIVE blocks
JCGoran Oct 21, 2024
5f4a00a
Update tests for CVODE
JCGoran Oct 21, 2024
38a796f
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 21, 2024
ea07cbc
Update docs
JCGoran Oct 21, 2024
e30c27c
Update docs
JCGoran Oct 21, 2024
80dbe90
Better naming
JCGoran Oct 22, 2024
6700597
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 22, 2024
ddeef2b
Fix for #1529
JCGoran Oct 22, 2024
e1f715b
Add voltage to `update_stiff`
JCGoran Oct 23, 2024
e4c64e8
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 23, 2024
167d38f
Address comments from review
JCGoran Oct 24, 2024
671e5e0
Merge branch 'jelic/cvode_visitors' into jelic/cvode_codegen_only
JCGoran Oct 24, 2024
11a2ae1
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 28, 2024
de609a8
Codegen
JCGoran Oct 28, 2024
04b2c94
Merge branch 'master' into jelic/cvode_codegen_only
JCGoran Oct 28, 2024
aa34bc9
Refactor with less repetition
JCGoran Oct 28, 2024
01c6514
Rename pytest test
JCGoran Oct 28, 2024
361172c
Set `cvode_ieq` as the variable name for CVODE
JCGoran Oct 28, 2024
25ff744
Remove `method_name`
JCGoran Oct 28, 2024
3acc4b3
Move method descriptions to header
JCGoran Oct 28, 2024
546a695
Update docstring format
JCGoran Oct 29, 2024
9a769da
Fix wording
JCGoran Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/codegen/codegen_helper_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,11 @@ void CodegenHelperVisitor::visit_nrn_state_block(const ast::NrnStateBlock& node)
node.visit_children(*this);
}

void CodegenHelperVisitor::visit_cvode_block(const ast::CvodeBlock& node) {
info.cvode_block = &node;
node.visit_children(*this);
}


void CodegenHelperVisitor::visit_procedure_block(const ast::ProcedureBlock& node) {
info.procedures.push_back(&node);
Expand Down
1 change: 1 addition & 0 deletions src/codegen/codegen_helper_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class CodegenHelperVisitor: public visitor::ConstAstVisitor {
void visit_program(const ast::Program& node) override;
void visit_factor_def(const ast::FactorDef& node) override;
void visit_nrn_state_block(const ast::NrnStateBlock& node) override;
void visit_cvode_block(const ast::CvodeBlock& node) override;
void visit_linear_block(const ast::LinearBlock& node) override;
void visit_non_linear_block(const ast::NonLinearBlock& node) override;
void visit_discrete_block(const ast::DiscreteBlock& node) override;
Expand Down
3 changes: 3 additions & 0 deletions src/codegen/codegen_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ struct CodegenInfo {
/// nrn_state block
const ast::NrnStateBlock* nrn_state_block = nullptr;

/// the CVODE block
const ast::CvodeBlock* cvode_block = nullptr;

/// net receive block for point process
const ast::NetReceiveBlock* net_receive_node = nullptr;

Expand Down
21 changes: 21 additions & 0 deletions src/codegen/codegen_naming.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,27 @@ static constexpr char THREAD_ARGS_PROTO[] = "_threadargsproto_";
/// prefix for ion variable
static constexpr char ION_VARNAME_PREFIX[] = "ion_";

/// name of CVODE method for counting # of ODEs
static constexpr char CVODE_COUNT_NAME[] = "ode_count";

/// name of CVODE method for updating non-stiff systems
static constexpr char CVODE_UPDATE_NON_STIFF_NAME[] = "ode_update_nonstiff";

/// name of CVODE method for updating stiff systems
static constexpr char CVODE_UPDATE_STIFF_NAME[] = "ode_update_stiff";

/// name of CVODE method for setting up non-stiff systems
static constexpr char CVODE_SETUP_NON_STIFF_NAME[] = "ode_setup_nonstiff";

/// name of CVODE method for setting up stiff systems
static constexpr char CVODE_SETUP_STIFF_NAME[] = "ode_setup_stiff";

/// name of CVODE method for setting up tolerances
static constexpr char CVODE_SETUP_TOLERANCES_NAME[] = "ode_setup_tolerances";

/// name of the CVODE variable (can be arbitrary)
static constexpr char CVODE_VARIABLE_NAME[] = "cvode_ieq";

/// commonly used variables in verbatim block and how they
/// should be mapped to new code generation backends
// clang-format off
Expand Down
156 changes: 152 additions & 4 deletions src/codegen/codegen_neuron_cpp_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,13 @@ void CodegenNeuronCppVisitor::print_mechanism_global_var_structure(bool print_in
printer->fmt_line("static Symbol* _{}_sym;", ion.name);
}

if (info.emit_cvode) {
printer->add_line("static Symbol** _atollist;");
printer->push_block("static HocStateTolerance _hoc_state_tol[] =");
printer->add_line("{0, 0}");
printer->pop_block(";");
}

printer->add_line("static int mech_type;");

if (info.point_process) {
Expand Down Expand Up @@ -1422,16 +1429,22 @@ void CodegenNeuronCppVisitor::print_mechanism_register_regular() {
i));
}

if (info.emit_cvode) {
mech_register_args.push_back(
fmt::format("_nrn_mechanism_field<int>{{\"{}\", \"cvodeieq\"}} /* {} */",
naming::CVODE_VARIABLE_NAME,
codegen_int_variables_size));
1uc marked this conversation as resolved.
Show resolved Hide resolved
}

printer->add_multi_line(fmt::format("{}", fmt::join(mech_register_args, ",\n")));

printer->decrease_indent();
printer->add_line(");");
printer->add_newline();


printer->fmt_line("hoc_register_prop_size(mech_type, {}, {});",
float_variables_size(),
int_variables_size());
int_variables_size() + static_cast<int>(info.emit_cvode));
1uc marked this conversation as resolved.
Show resolved Hide resolved

for (int i = 0; i < codegen_int_variables_size; ++i) {
if (i != info.semantics[i].index) {
Expand Down Expand Up @@ -1495,8 +1508,20 @@ void CodegenNeuronCppVisitor::print_mechanism_register_regular() {
printer->fmt_line("{}._morphology_sym = hoc_lookup(\"morphology\");",
global_struct_instance());
}

if (info.emit_cvode) {
printer->fmt_line("hoc_register_dparam_semantics(mech_type, {}, \"cvodeieq\");",
codegen_int_variables_size);
printer->fmt_line("hoc_register_cvode(mech_type, {}, {}, {}, {});",
method_name(naming::CVODE_COUNT_NAME),
method_name(naming::CVODE_SETUP_TOLERANCES_NAME),
method_name(naming::CVODE_SETUP_NON_STIFF_NAME),
method_name(naming::CVODE_SETUP_STIFF_NAME));
printer->fmt_line("hoc_register_tolerance(mech_type, _hoc_state_tol, &_atollist);");
}
}


void CodegenNeuronCppVisitor::print_mechanism_register_nothing() {
printer->add_line("hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc);");
}
Expand Down Expand Up @@ -1929,9 +1954,9 @@ void CodegenNeuronCppVisitor::print_nrn_alloc() {
)CODE");
printer->chain_block("else");
}
if (info.semantic_variable_count) {
if (info.semantic_variable_count || info.emit_cvode) {
printer->fmt_line("_ppvar = nrn_prop_datum_alloc(mech_type, {}, _prop);",
info.semantic_variable_count);
info.semantic_variable_count + static_cast<int>(info.emit_cvode));
JCGoran marked this conversation as resolved.
Show resolved Hide resolved
printer->add_line("_nrn_mechanism_access_dparam(_prop) = _ppvar;");
}
printer->add_multi_line(R"CODE(
Expand Down Expand Up @@ -2373,6 +2398,8 @@ void CodegenNeuronCppVisitor::print_mechanism_variables_macros() {
if (info.table_count > 0) {
printer->add_line("void _nrn_thread_table_reg(int, nrn_thread_table_check_t);");
}
// for CVODE
printer->add_line("extern void _cvode_abstol(Symbol**, double*, int);");
if (info.for_netcon_used) {
printer->add_line("int _nrn_netcon_args(void*, double***);");
}
Expand Down Expand Up @@ -2446,6 +2473,7 @@ void CodegenNeuronCppVisitor::print_codegen_routines_regular() {
print_nrn_alloc();
print_function_prototypes();
print_longitudinal_diffusion_callbacks();
print_cvode_definitions();
print_point_process_function_definitions();
print_setdata_functions();
print_check_table_entrypoint();
Expand Down Expand Up @@ -2594,6 +2622,126 @@ void CodegenNeuronCppVisitor::print_net_receive_common_code() {
printer->add_line("double t = nt->_t;");
}

CodegenCppVisitor::ParamVector CodegenNeuronCppVisitor::cvode_setup_parameters() {
return {{"", "const _nrn_model_sorted_token&", "", "_sorted_token"},
{"", "NrnThread*", "", "nt"},
{"", "Memb_list*", "", "_ml_arg"},
{"", "int", "", "_type"}};
}

CodegenCppVisitor::ParamVector CodegenNeuronCppVisitor::cvode_update_parameters() {
ParamVector args = {{"", "_nrn_mechanism_cache_range&", "", "_lmc"},
{"", fmt::format("{}_Instance&", info.mod_suffix), "", "inst"},
{"", fmt::format("{}_NodeData&", info.mod_suffix), "", "node_data"},
{"", "size_t", "", "id"},
{"", "Datum*", "", "_ppvar"},
{"", "Datum*", "", "_thread"},
{"", "NrnThread*", "", "nt"}};

if (info.thread_callback_register) {
auto type_name = fmt::format("{}&", thread_variables_struct());
args.emplace_back("", type_name, "", "_thread_vars");
}
return args;
}


void CodegenNeuronCppVisitor::print_cvode_count() {
printer->fmt_push_block("static constexpr int {}(int _type)",
method_name(naming::CVODE_COUNT_NAME));
printer->fmt_line("return {};", info.cvode_block->get_n_odes()->get_value());
printer->pop_block();
printer->add_newline(2);
}

void CodegenNeuronCppVisitor::print_cvode_tolerances() {
const CodegenNeuronCppVisitor::ParamVector tolerances_parameters = {
{"", "Prop*", "", "_prop"},
{"", "int", "", "equation_index"},
{"", "neuron::container::data_handle<double>*", "", "_pv"},
{"", "neuron::container::data_handle<double>*", "", "_pvdot"},
{"", "double*", "", "_atol"},
{"", "int", "", "_type"}};

auto get_param_name = [](const auto& item) { return std::get<3>(item); };

auto prop_name = get_param_name(tolerances_parameters[0]);
auto eqindex_name = get_param_name(tolerances_parameters[1]);
auto pv_name = get_param_name(tolerances_parameters[2]);
auto pvdot_name = get_param_name(tolerances_parameters[3]);
auto atol_name = get_param_name(tolerances_parameters[4]);

printer->fmt_push_block("static void {}({})",
method_name(naming::CVODE_SETUP_TOLERANCES_NAME),
get_parameter_str(tolerances_parameters));
printer->fmt_line("auto* _ppvar = _nrn_mechanism_access_dparam({});", prop_name);
printer->fmt_line("_ppvar[{}].literal_value<int>() = {};", int_variables_size(), eqindex_name);
printer->fmt_push_block("for (int i = 0; i < {}(0); i++)",
method_name(naming::CVODE_COUNT_NAME));
printer->fmt_line("{}[i] = _nrn_mechanism_get_param_handle({}, _slist1[i]);",
pv_name,
prop_name);
printer->fmt_line("{}[i] = _nrn_mechanism_get_param_handle({}, _dlist1[i]);",
pvdot_name,
prop_name);
printer->fmt_line("_cvode_abstol(_atollist, {}, i);", atol_name);
printer->pop_block();
printer->pop_block();
printer->add_newline(2);
}

void CodegenNeuronCppVisitor::print_cvode_update(const std::string& name,
const ast::StatementBlock& block) {
printer->fmt_push_block("static int {}({})",
method_name(name),
get_parameter_str(cvode_update_parameters()));
printer->add_line(
"auto v = node_data.node_voltages ? "
"node_data.node_voltages[node_data.nodeindices[id]] : 0.0;");

print_statement_block(block, false, false);

printer->add_line("return 0;");
printer->pop_block();
printer->add_newline(2);
}

void CodegenNeuronCppVisitor::print_cvode_setup(const std::string& setup_name,
const std::string& update_name) {
printer->fmt_push_block("static void {}({})",
method_name(setup_name),
get_parameter_str(cvode_setup_parameters()));
print_entrypoint_setup_code_from_memb_list();
printer->fmt_line("auto nodecount = _ml_arg->nodecount;");
printer->push_block("for (int id = 0; id < nodecount; id++)");
printer->add_line("auto* _ppvar = _ml_arg->pdata[id];");
printer->add_line(
"auto v = node_data.node_voltages ? "
"node_data.node_voltages[node_data.nodeindices[id]] : 0.0;");
printer->fmt_line("{}({});", method_name(update_name), get_arg_str(cvode_update_parameters()));

printer->pop_block();
printer->pop_block();

printer->add_newline(2);
}

void CodegenNeuronCppVisitor::print_cvode_definitions() {
if (!info.emit_cvode) {
return;
}

printer->add_newline(2);
printer->add_line("/* Functions related to CVODE codegen */");
print_cvode_count();
print_cvode_tolerances();
print_cvode_update(naming::CVODE_UPDATE_NON_STIFF_NAME,
*info.cvode_block->get_non_stiff_block());
print_cvode_update(naming::CVODE_UPDATE_STIFF_NAME, *info.cvode_block->get_stiff_block());
print_cvode_setup(naming::CVODE_SETUP_NON_STIFF_NAME, naming::CVODE_UPDATE_NON_STIFF_NAME);
print_cvode_setup(naming::CVODE_SETUP_STIFF_NAME, naming::CVODE_UPDATE_STIFF_NAME);
}

void CodegenNeuronCppVisitor::print_net_receive() {
printing_net_receive = true;
auto node = info.net_receive_node;
Expand Down
34 changes: 34 additions & 0 deletions src/codegen/codegen_neuron_cpp_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,40 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor {
void print_ion_variable() override;


/**
* Get the parameters for functions that setup (initialize) CVODE
*
*/
ParamVector cvode_setup_parameters();


/**
* Get the parameters for functions that update state at given timestep in CVODE
*
*/
ParamVector cvode_update_parameters();


/**
* Print all callbacks for CVODE
*
*/
void print_cvode_definitions();

/* print the CVODE function returning the # of ODEs to solve */
JCGoran marked this conversation as resolved.
Show resolved Hide resolved
void print_cvode_count();

/* print the CVODE function for setup of tolerances */
void print_cvode_tolerances();

/* print the CVODE update function ``name`` from ``block`` */
JCGoran marked this conversation as resolved.
Show resolved Hide resolved
void print_cvode_update(const std::string& name, const ast::StatementBlock& block);

/* print the CVODE setup function ``setup_name`` that calls the CVODE update function
* ``update_name`` */
void print_cvode_setup(const std::string& setup_name, const std::string& update_name);


/****************************************************************************************/
/* Overloaded visitor routines */
/****************************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions test/usecases/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set(NMODL_USECASE_DIRS
builtin_functions
constant
constructor
cvode
electrode_current
external
function
Expand Down
37 changes: 37 additions & 0 deletions test/usecases/cvode/derivative.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
NEURON {
SUFFIX scalar
}

PARAMETER {
freq = 10
a = 5
v1 = -1
v2 = 5
v3 = 15
v4 = 0.8
v5 = 0.3
r = 3
k = 0.2
}

STATE {var1 var2 var3}

INITIAL {
var1 = v1
var2 = v2
var3 = v3
}

BREAKPOINT {
SOLVE equation METHOD derivimplicit
}


DERIVATIVE equation {
: eq with a function on RHS
var1' = -sin(freq * t)
: simple ODE (nonzero Jacobian)
var2' = -var2 * a
: logistic ODE
var3' = r * var3 * (1 - var3 / k)
JCGoran marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading