NEURON
cvtrset.cpp
Go to the documentation of this file.
1 #include "nrnconf.h"
2 #include <stdio.h>
3 #include <errno.h>
4 #include <math.h>
5 #include "nrnoc2iv.h"
6 #include "cvodeobj.h"
7 #include "nonvintblock.h"
8 
9 #include "membfunc.h"
10 #include "neuron.h"
11 
12 void Cvode::rhs(neuron::model_sorted_token const& sorted_token, NrnThread* _nt) {
13  CvodeThreadData& z = CTD(_nt->id);
14  if (diam_changed) {
15  recalc_diam();
16  }
17  if (z.rootnode_end_index_ == 0) {
18  return;
19  }
20  auto* const vec_rhs = _nt->node_rhs_storage();
21  for (int i = z.rootnode_begin_index_; i < z.rootnode_end_index_; ++i) {
22  vec_rhs[i] = 0.;
23  }
24  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
25  vec_rhs[i] = 0.;
26  }
27  auto const vec_sav_rhs = _nt->node_sav_rhs_storage();
28  if (vec_sav_rhs) {
29  for (int i = z.rootnode_begin_index_; i < z.rootnode_end_index_; ++i) {
30  vec_sav_rhs[i] = 0.;
31  }
32  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
33  vec_sav_rhs[i] = 0.;
34  }
35  }
36 
37  rhs_memb(sorted_token, z.cv_memb_list_, _nt);
39 
40  if (vec_sav_rhs) {
41  for (int i = z.rootnode_begin_index_; i < z.rootnode_end_index_; ++i) {
42  vec_sav_rhs[i] -= vec_rhs[i];
43  }
44  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
45  vec_sav_rhs[i] -= vec_rhs[i];
46  }
47  }
48 
49  /* at this point d contains all the membrane conductances */
50  /* now the internal axial currents.
51  rhs += ai_j*(vi_j - vi)
52  */
53  auto const vec_a = _nt->node_a_storage();
54  auto const vec_b = _nt->node_b_storage();
55  auto const vec_v = _nt->node_voltage_storage();
56  auto* const parents = _nt->_v_parent_index;
57  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
58  auto const parent_i = parents[i];
59  auto const dv = vec_v[parent_i] - vec_v[i];
60  // our connection coefficients are negative so
61  vec_rhs[i] -= vec_b[i] * dv;
62  vec_rhs[parent_i] += vec_a[i] * dv;
63  }
64 }
65 
67  CvMembList* cmlist,
68  NrnThread* _nt) {
69  errno = 0;
70  for (CvMembList* cml = cmlist; cml; cml = cml->next) {
71  const Memb_func& mf = memb_func[cml->index];
72  if (auto const current = mf.current; current) {
73  for (auto& ml: cml->ml) {
74  current(sorted_token, _nt, &ml, cml->index);
75  if (errno && nrn_errno_check(cml->index)) {
76  hoc_warning("errno set during calculation of currents", nullptr);
77  }
78  }
79  }
80  }
82  activstim_rhs();
84 }
85 
86 void Cvode::lhs(neuron::model_sorted_token const& sorted_token, NrnThread* _nt) {
87  int i;
88 
89  CvodeThreadData& z = CTD(_nt->id);
90  if (z.rootnode_end_index_ == 0) {
91  return;
92  }
93  auto* const vec_d = _nt->node_d_storage();
94  for (int i = z.rootnode_begin_index_; i < z.rootnode_end_index_; ++i) {
95  vec_d[i] = 0.;
96  }
97  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
98  vec_d[i] = 0.;
99  }
100 
101  lhs_memb(sorted_token, z.cv_memb_list_, _nt);
103  for (auto& ml: z.cmlcap_->ml) {
104  nrn_cap_jacob(sorted_token, _nt, &ml);
105  }
106 
107  // fast_imem not needed since exact icap added in nrn_div_capacity
108 
109  /* now add the axial currents */
110  auto* const vec_a = _nt->node_a_storage();
111  auto* const vec_b = _nt->node_b_storage();
112  auto* const parent_i = _nt->_v_parent_index;
113  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
114  vec_d[i] -= vec_b[i];
115  vec_d[parent_i[i]] -= vec_a[i];
116  }
117 }
118 
120  CvMembList* cmlist,
121  NrnThread* _nt) {
122  CvMembList* cml;
123  for (cml = cmlist; cml; cml = cml->next) {
124  const Memb_func& mf = memb_func[cml->index];
125  if (auto const jacob = mf.jacob; jacob) {
126  for (auto& ml: cml->ml) {
127  jacob(sorted_token, _nt, &ml, cml->index);
128  if (errno && nrn_errno_check(cml->index)) {
129  hoc_warning("errno set during calculation of di/dv", nullptr);
130  }
131  }
132  }
133  }
135  activclamp_lhs();
136 }
137 
138 /* triangularization of the matrix equations */
140  CvodeThreadData& z = CTD(_nt->id);
141 
142  auto* const vec_a = _nt->node_a_storage();
143  auto* const vec_b = _nt->node_b_storage();
144  auto* const vec_d = _nt->node_d_storage();
145  auto* const vec_rhs = _nt->node_rhs_storage();
146  for (int i = z.vnode_end_index_ - 1; i >= z.vnode_begin_index_; --i) {
147  double const p = vec_a[i] / vec_d[i];
148  auto const parent_i = _nt->_v_parent_index[i];
149  vec_d[parent_i] -= p * vec_b[i];
150  vec_rhs[parent_i] -= p * vec_rhs[i];
151  }
152 }
153 
154 /* back substitution to finish solving the matrix equations */
156  CvodeThreadData& z = CTD(_nt->id);
157 
158  auto* const vec_b = _nt->node_b_storage();
159  auto* const vec_d = _nt->node_d_storage();
160  auto* const vec_rhs = _nt->node_rhs_storage();
161  auto* const parent_i = _nt->_v_parent_index;
162  for (int i = z.rootnode_begin_index_; i < z.rootnode_end_index_; ++i) {
163  vec_rhs[i] /= vec_d[i];
164  }
165  for (int i = z.vnode_begin_index_; i < z.vnode_end_index_; ++i) {
166  vec_rhs[i] -= vec_b[i] * vec_rhs[parent_i[i]];
167  vec_rhs[i] /= vec_d[i];
168  }
169 }
void activclamp_lhs(void)
Definition: clamp.cpp:190
void activclamp_rhs(void)
Definition: clamp.cpp:172
void rhs(neuron::model_sorted_token const &, NrnThread *)
Definition: cvtrset.cpp:12
void rhs_memb(neuron::model_sorted_token const &, CvMembList *, NrnThread *)
Definition: cvtrset.cpp:66
void triang(NrnThread *)
Definition: cvtrset.cpp:139
void bksub(NrnThread *)
Definition: cvtrset.cpp:155
void lhs_memb(neuron::model_sorted_token const &, CvMembList *, NrnThread *)
Definition: cvtrset.cpp:119
void lhs(neuron::model_sorted_token const &, NrnThread *)
Definition: cvtrset.cpp:86
int vnode_begin_index_
Definition: cvodeobj.h:80
int vnode_end_index_
Definition: cvodeobj.h:81
CvMembList * cv_memb_list_
Definition: cvodeobj.h:62
int rootnode_begin_index_
Definition: cvodeobj.h:78
CvMembList * cmlcap_
Definition: cvodeobj.h:63
int rootnode_end_index_
Definition: cvodeobj.h:79
#define i
Definition: md1redef.h:19
#define CTD(i)
Definition: cvodeobj.h:53
int nrn_errno_check(int i)
Definition: fadvance.cpp:767
void activstim_rhs(void)
Definition: fstim.cpp:162
void hoc_warning(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:44
int diam_changed
Definition: nrnoc_aux.cpp:21
auto *const vec_d
Definition: cellorder.cpp:615
auto *const vec_b
Definition: cellorder.cpp:614
auto *const vec_rhs
Definition: cellorder.cpp:616
#define nrn_nonvint_block_current(size, rhs, tid)
Definition: nonvintblock.h:43
#define nrn_nonvint_block_conductance(size, d, tid)
Definition: nonvintblock.h:48
void activsynapse_rhs(void)
Definition: synapse.cpp:206
void activsynapse_lhs(void)
Definition: synapse.cpp:215
void recalc_diam(void)
Definition: treeset.cpp:923
size_t p
std::vector< Memb_func > memb_func
Definition: init.cpp:145
void nrn_cap_jacob(neuron::model_sorted_token const &sorted_token, NrnThread *_nt, Memb_list *ml)
Definition: capac.cpp:39
static List * current
Definition: nrnunit.cpp:13
Wrapper for Memb_list in CVode related code.
Definition: cvodeobj.h:35
std::vector< Memb_list > ml
Definition: cvodeobj.h:41
int index
Definition: cvodeobj.h:42
CvMembList * next
Definition: cvodeobj.h:40
nrn_jacob_t jacob
Definition: membfunc.h:61
nrn_cur_t current
Definition: membfunc.h:60
Represent main neuron object computed by single thread.
Definition: multicore.h:58
int * _v_parent_index
Definition: multicore.h:89
double * node_a_storage()
Definition: multicore.cpp:1054
int id
Definition: multicore.h:66
double * node_sav_rhs_storage()
Definition: multicore.cpp:1088
double * node_rhs_storage()
Definition: multicore.cpp:1074
int end
Definition: multicore.h:65
double * node_d_storage()
Definition: multicore.cpp:1069
double * node_voltage_storage()
Definition: multicore.cpp:1098
double * node_b_storage()
Definition: multicore.cpp:1064