NEURON
segment_diam.cpp
Go to the documentation of this file.
1 // NOTE: this assumes neuronapi.h is on your CPLUS_INCLUDE_PATH
2 // Exercises nrn_segment_diam_get's lazy recompute of 3d-derived diameter.
3 // When a section's geometry comes from pt3dadd, NEURON rewrites the segment
4 // diam lazily (gated per-section on recalc_area_). nrn_segment_diam_get must
5 // trigger that recompute so a read before any geometry pass returns the
6 // 3d-derived value, matching what Python's seg.diam already does.
7 #include <array>
8 #include <cmath>
9 #include <iostream>
10 #include "neuronapi.h"
11 
12 using std::cerr;
13 using std::endl;
14 
15 extern "C" void modl_reg(){/* No modl_reg */};
16 
17 static bool close_to(double got, double want, const char* msg) {
18  if (std::fabs(got - want) > 1e-9) {
19  cerr << "FAIL: " << msg << " — got " << got << ", want " << want << endl;
20  return false;
21  }
22  return true;
23 }
24 
25 static void pt3dadd(Section* sec, double xx, double yy, double zz, double diam) {
27  nrn_double_push(xx);
28  nrn_double_push(yy);
29  nrn_double_push(zz);
30  nrn_double_push(diam);
31  nrn_function_call(nrn_symbol("pt3dadd"), 4);
32  nrn_double_pop(); // pt3dadd returns a number
34 }
35 
36 int main(void) {
37  static std::array<const char*, 4> argv = {"segment_diam", "-nogui", "-nopython", nullptr};
38  nrn_init(3, argv.data());
39 
40  // Uniform 3d geometry: two points, both diam 10, so diam is 10 everywhere.
41  Section* s = nrn_section_new("s");
42  pt3dadd(s, 0, 0, 0, 10);
43  pt3dadd(s, 10, 0, 0, 10);
44 
45  bool ok = true;
46 
47  // Read BEFORE any geometry pass. Without the recompute this returns the
48  // 500.0 default; with it, the 3d-derived 10.0.
49  ok &= close_to(nrn_segment_diam_get(s, 0.5), 10.0, "diam read before geometry pass");
50 
51  // A geometry pass must not change the already-correct value.
52  nrn_double_push(-65);
53  nrn_function_call(nrn_symbol("finitialize"), 1);
55  ok &= close_to(nrn_segment_diam_get(s, 0.5), 10.0, "diam read after finitialize");
56 
57  return ok ? 0 : 1;
58 }
#define sec
Definition: md1redef.h:20
static char ** argv
Definition: inithoc.cpp:46
static void nrn_init(neuron::model_sorted_token const &, NrnThread *nt, Memb_list *ml, int type)
Definition: kschan.cpp:69
fabs
Definition: extdef.h:3
void nrn_section_pop(void)
Definition: neuronapi.cpp:143
Symbol * nrn_symbol(char const *const name)
Definition: neuronapi.cpp:246
double nrn_double_pop(void)
Definition: neuronapi.cpp:288
void nrn_section_push(Section *sec)
Definition: neuronapi.cpp:139
Section * nrn_section_new(char const *const name)
Definition: neuronapi.cpp:76
void nrn_function_call(Symbol *sym, int narg)
Definition: neuronapi.cpp:382
void nrn_double_push(double val)
Definition: neuronapi.cpp:284
double nrn_segment_diam_get(Section *const sec, const double x)
Definition: neuronapi.cpp:198
s
Definition: multisend.cpp:521
static bool close_to(double got, double want, const char *msg)
void modl_reg()
int main(void)
static void pt3dadd(Section *sec, double xx, double yy, double zz, double diam)