NEURON
node.hpp
Go to the documentation of this file.
1 #pragma once
2 #include "membdef.h" // DEF_vrest
5 
6 #include <algorithm>
7 #include <cassert>
8 #include <functional>
9 #include <memory>
10 
12 namespace field {
13 
14 /**
15  * @brief Above-diagonal element in node equation.
16  */
17 struct AboveDiagonal {
18  using type = double;
19 };
20 
21 /**
22  * @brief Area in um^2 but see treeset.cpp.
23  */
24 struct Area {
25  using type = double;
26  constexpr type default_value() const {
27  return 100.;
28  }
29 };
30 
31 /**
32  * @brief Below-diagonal element in node equation.
33  */
34 struct BelowDiagonal {
35  using type = double;
36 };
37 
38 /** @brief Membrane potential.
39  */
40 struct Voltage {
41  using type = double;
42  constexpr type default_value() const {
43  return DEF_vrest;
44  }
45 };
46 
47 /**
48  * @brief Diagonal element in node equation.
49  */
50 struct Diagonal {
51  using type = double;
52 };
53 
54 /**
55  * @brief Field for fast_imem calculation.
56  */
57 struct FastIMemSavD {
58  static constexpr bool optional = true;
59  using type = double;
60 };
61 
62 /**
63  * @brief Field for fast_imem calculation.
64  */
66  static constexpr bool optional = true;
67  using type = double;
68 };
69 
70 struct RHS {
71  using type = double;
72 };
73 
74 } // namespace field
75 
76 /**
77  * @brief Base class defining the public API of Node handles.
78  * @tparam Identifier The concrete owning/non-owning identifier type.
79  *
80  * This allows the same struct-like accessors (v(), ...) to be
81  * used on all of the different types of objects that represent a single Node:
82  * - owning_handle: stable over permutations of underlying data, manages
83  * lifetime of a row in the underlying storage. Only null when in moved-from
84  * state.
85  * - handle: stable over permutations of underlying data, produces runtime error
86  * if it is dereferenced after the corresponding owning_handle has gone out of
87  * scope. Can be null.
88  */
89 template <typename Identifier>
90 struct handle_interface: handle_base<Identifier> {
92  using base_type::base_type;
93  /**
94  * @brief Return the above-diagonal element.
95  */
96  [[nodiscard]] field::AboveDiagonal::type& a() {
97  return this->template get<field::AboveDiagonal>();
98  }
99 
100  /**
101  * @brief Return the above-diagonal element.
102  */
103  [[nodiscard]] field::AboveDiagonal::type const& a() const {
104  return this->template get<field::AboveDiagonal>();
105  }
106 
107  /** @brief Return the area.
108  */
109  [[nodiscard]] field::Area::type& area() {
110  return this->template get<field::Area>();
111  }
112 
113  /** @brief Return the area.
114  */
115  [[nodiscard]] field::Area::type const& area() const {
116  return this->template get<field::Area>();
117  }
118 
119  /**
120  * @brief This is a workaround for area sometimes being a macro.
121  * @todo Remove those macros once and for all.
122  */
123  [[nodiscard]] field::Area::type& area_hack() {
124  return area();
125  }
126 
127  /**
128  * @brief This is a workaround for area sometimes being a macro.
129  * @todo Remove those macros once and for all.
130  */
131  [[nodiscard]] field::Area::type const& area_hack() const {
132  return area();
133  }
134 
135  /** @brief Return a data_handle to the area.
136  */
138  return this->template get_handle<field::Area>();
139  }
140 
141  /**
142  * @brief Return the below-diagonal element.
143  */
144  [[nodiscard]] field::BelowDiagonal::type& b() {
145  return this->template get<field::BelowDiagonal>();
146  }
147 
148  /**
149  * @brief Return the below-diagonal element.
150  */
151  [[nodiscard]] field::BelowDiagonal::type const& b() const {
152  return this->template get<field::BelowDiagonal>();
153  }
154 
155  /**
156  * @brief Return the diagonal element.
157  */
158  [[nodiscard]] field::Diagonal::type& d() {
159  return this->template get<field::Diagonal>();
160  }
161 
162  /**
163  * @brief Return the diagonal element.
164  */
165  [[nodiscard]] field::Diagonal::type const& d() const {
166  return this->template get<field::Diagonal>();
167  }
168 
169  /**
170  * @brief Return the membrane potential.
171  */
172  [[nodiscard]] field::Voltage::type& v() {
173  return this->template get<field::Voltage>();
174  }
175 
176  /**
177  * @brief Return the membrane potential.
178  */
179  [[nodiscard]] field::Voltage::type const& v() const {
180  return this->template get<field::Voltage>();
181  }
182 
183  /**
184  * @brief Return a handle to the membrane potential.
185  */
187  return this->template get_handle<field::Voltage>();
188  }
189 
190  /**
191  * @brief This is a workaround for v sometimes being a macro.
192  * @todo Remove those macros once and for all.
193  */
194  [[nodiscard]] field::Voltage::type& v_hack() {
195  return v();
196  }
197 
198  /**
199  * @brief This is a workaround for v sometimes being a macro.
200  * @todo Remove those macros once and for all.
201  */
202  [[nodiscard]] field::Voltage::type const& v_hack() const {
203  return v();
204  }
205 
206  /**
207  * @brief Return the right hand side of the Hines solver.
208  */
209  [[nodiscard]] field::RHS::type& rhs() {
210  return this->template get<field::RHS>();
211  }
212 
213  /**
214  * @brief Return the right hand side of the Hines solver.
215  */
216  [[nodiscard]] field::RHS::type const& rhs() const {
217  return this->template get<field::RHS>();
218  }
219 
220  /**
221  * @brief Return a handle to the right hand side of the Hines solver.
222  */
224  return this->template get_handle<field::RHS>();
225  }
226 
228  return this->template get<field::FastIMemSavD>();
229  }
230 
231  [[nodiscard]] field::FastIMemSavRHS::type const& sav_d() const {
232  return this->template get<field::FastIMemSavD>();
233  }
234 
236  return this->template get<field::FastIMemSavRHS>();
237  }
238 
239  [[nodiscard]] field::FastIMemSavRHS::type const& sav_rhs() const {
240  return this->template get<field::FastIMemSavRHS>();
241  }
243  return this->template get_handle<field::FastIMemSavRHS>();
244  }
245 
246  friend std::ostream& operator<<(std::ostream& os, handle_interface const& handle) {
247  if (handle.id()) {
248  return os << "Node{" << handle.id() << '/' << handle.underlying_storage().size()
249  << " v=" << handle.v() << " area=" << handle.area() << " a=" << handle.a()
250  << " b=" << handle.b() << " d=" << handle.d() << '}';
251  } else {
252  return os << "Node{null}";
253  }
254  }
255 };
256 } // namespace neuron::container::Node
#define DEF_vrest
Above-diagonal element in node equation.
Definition: node.hpp:17
Area in um^2 but see treeset.cpp.
Definition: node.hpp:24
constexpr type default_value() const
Definition: node.hpp:26
Below-diagonal element in node equation.
Definition: node.hpp:34
Diagonal element in node equation.
Definition: node.hpp:50
Field for fast_imem calculation.
Definition: node.hpp:57
Field for fast_imem calculation.
Definition: node.hpp:65
constexpr type default_value() const
Definition: node.hpp:42
Base class defining the public API of Node handles.
Definition: node.hpp:90
field::Diagonal::type & d()
Return the diagonal element.
Definition: node.hpp:158
data_handle< field::RHS::type > rhs_handle()
Return a handle to the right hand side of the Hines solver.
Definition: node.hpp:223
field::Voltage::type const & v_hack() const
This is a workaround for v sometimes being a macro.
Definition: node.hpp:202
field::Diagonal::type const & d() const
Return the diagonal element.
Definition: node.hpp:165
field::RHS::type & rhs()
Return the right hand side of the Hines solver.
Definition: node.hpp:209
field::RHS::type const & rhs() const
Return the right hand side of the Hines solver.
Definition: node.hpp:216
field::BelowDiagonal::type & b()
Return the below-diagonal element.
Definition: node.hpp:144
field::FastIMemSavRHS::type const & sav_rhs() const
Definition: node.hpp:239
friend std::ostream & operator<<(std::ostream &os, handle_interface const &handle)
Definition: node.hpp:246
field::Area::type const & area() const
Return the area.
Definition: node.hpp:115
field::Voltage::type & v_hack()
This is a workaround for v sometimes being a macro.
Definition: node.hpp:194
data_handle< field::FastIMemSavRHS::type > sav_rhs_handle()
Definition: node.hpp:242
field::AboveDiagonal::type & a()
Return the above-diagonal element.
Definition: node.hpp:96
field::Area::type & area()
Return the area.
Definition: node.hpp:109
field::FastIMemSavRHS::type & sav_rhs()
Definition: node.hpp:235
field::Area::type & area_hack()
This is a workaround for area sometimes being a macro.
Definition: node.hpp:123
field::FastIMemSavRHS::type & sav_d()
Definition: node.hpp:227
field::Area::type const & area_hack() const
This is a workaround for area sometimes being a macro.
Definition: node.hpp:131
field::AboveDiagonal::type const & a() const
Return the above-diagonal element.
Definition: node.hpp:103
field::FastIMemSavRHS::type const & sav_d() const
Definition: node.hpp:231
data_handle< field::Voltage::type > v_handle()
Return a handle to the membrane potential.
Definition: node.hpp:186
field::Voltage::type const & v() const
Return the membrane potential.
Definition: node.hpp:179
field::Voltage::type & v()
Return the membrane potential.
Definition: node.hpp:172
data_handle< field::Area::type > area_handle()
Return a data_handle to the area.
Definition: node.hpp:137
field::BelowDiagonal::type const & b() const
Return the below-diagonal element.
Definition: node.hpp:151
Stable handle to a generic value.
Definition: data_handle.hpp:61
Base class for neuron::container::soa<...> handles.
Definition: view_utils.hpp:34
auto & underlying_storage()
Obtain a reference to the storage this handle refers to.
Definition: view_utils.hpp:69
non_owning_identifier_without_container id() const
Obtain a lightweight identifier of the current entry.
Definition: view_utils.hpp:54