From 2a71b3f580d720cf8afd6172e84d1296c57f8c75 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Thu, 10 Oct 2024 08:58:14 +0200 Subject: [PATCH 1/4] Improve documentation. --- src/language/nmodl.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/language/nmodl.yaml b/src/language/nmodl.yaml index 0f76b01a3..de598cec3 100644 --- a/src/language/nmodl.yaml +++ b/src/language/nmodl.yaml @@ -1140,15 +1140,15 @@ type: Expression - NonLinEquation: - brief: "TODO" + brief: "One equation in a system of equations that collectively make a NONLINEAR block." nmodl: "~ " members: - lhs: - brief: "TODO" + brief: "Left-hand-side of the equation." type: Expression suffix: {value: " = "} - rhs: - brief: "TODO" + brief: "Right-hand-side of the equation." type: Expression - LinEquation: From ac7b0da7523d7e506e72139226e245c8dcc4be2c Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Thu, 10 Oct 2024 11:33:21 +0200 Subject: [PATCH 2/4] A `NONLINEAR` block requires `sympy --analytic`. --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 436ec2c4e..ba9de4a19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -516,6 +516,8 @@ int run_nmodl(int argc, const char* argv[]) { enable_sympy(solver_exists(*ast, "derivimplicit"), "'SOLVE ... METHOD derivimplicit'"); enable_sympy(node_exists(*ast, ast::AstNodeType::LINEAR_BLOCK), "'LINEAR' block"); + enable_sympy(node_exists(*ast, ast::AstNodeType::NON_LINEAR_BLOCK), + "'NONLINEAR' block"); enable_sympy(solver_exists(*ast, "sparse"), "'SOLVE ... METHOD sparse'"); } From 36eeee26843dff57d2326a166324b1a17eff0a5b Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Thu, 10 Oct 2024 11:49:24 +0200 Subject: [PATCH 3/4] Add trivial test. --- test/usecases/nonlinear/nonlin.mod | 21 +++++++++++++++++++++ test/usecases/nonlinear/test_nonlin.py | 15 +++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/usecases/nonlinear/nonlin.mod create mode 100644 test/usecases/nonlinear/test_nonlin.py diff --git a/test/usecases/nonlinear/nonlin.mod b/test/usecases/nonlinear/nonlin.mod new file mode 100644 index 000000000..ec0bed30f --- /dev/null +++ b/test/usecases/nonlinear/nonlin.mod @@ -0,0 +1,21 @@ +NEURON { + SUFFIX nonlin +} + +STATE { x } + +FUNCTION solve() { + : Iterative solvers need a starting guess. + x = 1.0 + SOLVE eq + + solve = x +} + +NONLINEAR eq { + ~ x*x = 4.0 +} + +FUNCTION residual(x) { + residual = x - 2.0 +} diff --git a/test/usecases/nonlinear/test_nonlin.py b/test/usecases/nonlinear/test_nonlin.py new file mode 100644 index 000000000..eef75edbd --- /dev/null +++ b/test/usecases/nonlinear/test_nonlin.py @@ -0,0 +1,15 @@ +from neuron import h, gui + + +def test_nonlin(): + s = h.Section() + s.insert("nonlin") + inst = s(0.5).nonlin + + x = inst.solve() + error = inst.residual(x) + assert abs(error) < 1e-9, f"{x = }, {error = }" + + +if __name__ == "__main__": + test_nonlin() From d0b0a38b2988133024b896828629f72983e766a6 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Mon, 14 Oct 2024 13:25:49 +0200 Subject: [PATCH 4/4] Register `nonlinear` tests. --- test/usecases/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/usecases/CMakeLists.txt b/test/usecases/CMakeLists.txt index feaa81ef7..4d0700fbc 100644 --- a/test/usecases/CMakeLists.txt +++ b/test/usecases/CMakeLists.txt @@ -17,6 +17,7 @@ set(NMODL_USECASE_DIRS net_receive net_send neuron_variables + nonlinear nonspecific_current parameter point_process