NEURON
clamp.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/nrnoc/clamp.cpp,v 1.2 1997/08/15 13:04:10 hines Exp */
3 
4 /* modified from fstim.cpp */
5 /* 4/9/2002 modified to conform to new treeset.cpp */
6 
7 /*
8 fclamp(maxlevel, loc)
9  allocates space for maxlevel level changes all at location loc
10  previously existing clamp is released.
11  All clamp levels are initialized to clamp_resist series resistance.
12  and 0 duration. After the final level change the clamp is off.
13 
14 fclamp(i, duration, vc)
15  the maxlevel level changes concatenate. This function specifies
16  the magnitude and duration of the ith level.
17 
18 fclampv()
19  the value of the clamp potential at the global time t
20 
21 fclampi()
22  the clamp current at the global time t
23 
24 */
25 
26 #include <stdlib.h>
27 #include "neuron.h"
28 #include "section.h"
29 #include "nrniv_mf.h"
30 
31 
32 static double loc;
33 static Node* pnd;
34 static Section* sec;
35 static double gtemp;
36 static int maxlevel = 0; /* size of clamp array */
37 static double *duration, *vc, *tswitch; /* maxlevel of them */
38 static int oldsw = 0;
39 
40 static double clampval();
41 
42 extern void clamp_prepare();
43 
44 #define nt_t nrn_threads->_t
45 
46 void print_clamp() {
47  int i;
48 
49  if (maxlevel == 0)
50  return;
51 #ifndef _OMPSS_
52  Printf(
53  "%s fclamp(%d, %g) /* Second arg is location */\n\
54 /* fclamp( #, duration(ms), magnitude(mV)) ; clamp_resist = %g */\n",
55  secname(sec),
56  maxlevel,
57  loc,
58  clamp_resist);
59 #else
60  Printf(
61  "%s fclamp(%d, %g) /* Second arg is location */\nfclamp( #, duration(ms), magnitude(mV)) ; "
62  "clamp_resist = %g */\n",
63  secname(sec),
64  maxlevel,
65  loc,
66  clamp_resist);
67 #endif
68  for (i = 0; i < maxlevel; i++) {
69  Printf(" fclamp(%2d,%13g,%14g)\n", i, duration[i], vc[i]);
70  }
71 }
72 
73 void fclampv(void) {
74  if (maxlevel) {
76  } else {
77  hoc_retpushx(0.);
78  }
79 }
80 
81 void fclampi(void) {
82  double v;
83 
84  if (maxlevel) {
85  v = clampval();
86  if (gtemp) {
88  } else {
89  hoc_retpushx(0.);
90  }
91  } else {
92  hoc_retpushx(0.);
93  }
94 }
95 
96 static void free_clamp(void);
97 
98 void fclamp(void) {
99  int i;
100 
101  if (nrn_nthread > 1) {
102  hoc_execerror("fsyn does not allow threads", "");
103  }
104  /* two args are maxlevel, loc */
105  /* three args are level, duration, vc */
106  i = chkarg(1, 0., 10000.);
107  if (ifarg(3)) {
108  int num;
109  if (i >= maxlevel) {
110  hoc_execerror("level index out of range", (char*) 0);
111  }
112  duration[i] = chkarg(2, 0., 1e21);
113  vc[i] = *getarg(3);
114 
115  tswitch[0] = -1e-9;
116  for (num = 0; num < maxlevel; num++) {
117  tswitch[num + 1] = tswitch[num] + duration[num];
118  }
119  oldsw = 0;
121  } else {
122  free_clamp();
123  maxlevel = i;
124  if (maxlevel) {
125  duration = (double*) emalloc((unsigned) (maxlevel * sizeof(double)));
126  vc = (double*) emalloc((unsigned) (maxlevel * sizeof(double)));
127  tswitch = (double*) emalloc((unsigned) ((maxlevel + 1) * sizeof(double)));
128  for (i = 0; i < maxlevel; i++) {
129  duration[i] = 0.;
130  vc[i] = 0.;
131  tswitch[i] = -1e-9;
132  }
133  tswitch[maxlevel] = -1e-9;
134  loc = chkarg(2, 0., 1.);
135  sec = chk_access();
136  section_ref(sec);
137  clamp_prepare();
138  }
139  }
140  hoc_retpushx(0.);
141 }
142 
143 static void free_clamp(void) {
144  if (maxlevel) {
145  free((char*) duration);
146  free((char*) vc);
147  free((char*) tswitch);
148  maxlevel = 0;
150  sec = 0;
151  }
152 }
153 
154 void clamp_prepare(void) /*fill in the section info*/
155 {
156  double area;
157 
158  if (!maxlevel) {
159  return;
160  }
161  if (sec->prop) {
162  pnd = node_ptr(sec, loc, &area);
163  } else {
164  free_clamp();
165  return;
166  }
167  if (clamp_resist <= 0) {
168  hoc_execerror("clamp_resist must be > 0 in megohms", (char*) 0);
169  }
170 }
171 
172 void activclamp_rhs(void) {
173  double v;
174  if (!maxlevel) {
175  return;
176  }
177  v = clampval();
178 #if EXTRACELLULAR
179  if (pnd->extnode) {
180  NODERHS(pnd) += gtemp * (v - NODEV(pnd) - pnd->extnode->v[0]);
181  } else {
182  NODERHS(pnd) += gtemp * (v - NODEV(pnd));
183  }
184 
185 #else
186  NODERHS(pnd) += gtemp * (v - NODEV(pnd));
187 #endif
188 }
189 
190 void activclamp_lhs(void) {
191  double v;
192  if (!maxlevel) {
193  return;
194  }
195  NODED(pnd) += gtemp;
196 }
197 
198 static double clampval(void) {
199  gtemp = 1.e2 / clamp_resist / NODEAREA(pnd);
200  for (;;) {
201 #if CVODE
203 #endif
204  if (nt_t < tswitch[oldsw]) {
205  if (oldsw == 0) {
206  break;
207  }
208 #if CVODE
209  /* for cvode the other was inefficient since t is non-monotonic */
210  --oldsw;
211 #else
212  oldsw = 0;
213 #endif
214  } else {
215  if (nt_t < tswitch[oldsw + 1]) {
216  break;
217  } else {
218  if (++oldsw == maxlevel) {
219  --oldsw;
220  gtemp = 0.;
221  break;
222  }
223  }
224  }
225  }
226  return vc[oldsw];
227 }
const char * secname(Section *sec)
Definition: cabcode.cpp:1776
Node * node_ptr(Section *sec, double x, double *parea)
Definition: cabcode.cpp:1986
Section * chk_access(void)
Definition: cabcode.cpp:444
static double * vc
Definition: clamp.cpp:37
void activclamp_lhs(void)
Definition: clamp.cpp:190
void fclamp(void)
Definition: clamp.cpp:98
static Section * sec
Definition: clamp.cpp:34
static int oldsw
Definition: clamp.cpp:38
static double loc
Definition: clamp.cpp:32
static void free_clamp(void)
Definition: clamp.cpp:143
static int maxlevel
Definition: clamp.cpp:36
void activclamp_rhs(void)
Definition: clamp.cpp:172
static double * duration
Definition: clamp.cpp:37
void fclampi(void)
Definition: clamp.cpp:81
void fclampv(void)
Definition: clamp.cpp:73
static Node * pnd
Definition: clamp.cpp:33
static double gtemp
Definition: clamp.cpp:35
#define nt_t
Definition: clamp.cpp:44
void clamp_prepare()
Definition: clamp.cpp:154
static double clampval()
Definition: clamp.cpp:198
void print_clamp()
Definition: clamp.cpp:46
static double * tswitch
Definition: clamp.cpp:37
double chkarg(int, double low, double high)
Definition: code2.cpp:638
at_time
Definition: extargs.h:1
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
void hoc_retpushx(double x)
Definition: hocusr.cpp:154
#define getarg
Definition: hocdec.h:15
int ifarg(int)
Definition: code.cpp:1581
#define area
Definition: md1redef.h:5
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
#define Printf
Definition: model.h:237
char * emalloc(unsigned n)
Definition: list.cpp:166
int nrn_nthread
Definition: multicore.cpp:46
NrnThread * nrn_threads
Definition: multicore.cpp:47
void section_ref(Section *)
Definition: solve.cpp:575
void section_unref(Section *)
Definition: solve.cpp:565
double clamp_resist
Definition: init.cpp:99
#define e
Definition: passive0.cpp:22
#define NODEV(n)
Definition: section.h:115
#define NODEAREA(n)
Definition: section.h:116
#define NODERHS(n)
Definition: section.h:105
#define NODED(n)
Definition: section.h:104
double * v
Definition: section.h:196
Definition: section.h:133
struct Extnode * extnode
Definition: section.h:161
struct Prop * prop
Definition: section.h:63