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) return;
50 #ifndef _OMPSS_
51  Printf("%s fclamp(%d, %g) /* Second arg is location */\n\
52 /* fclamp( #, duration(ms), magnitude(mV)) ; clamp_resist = %g */\n", secname(sec),
54 #else
55  Printf("%s fclamp(%d, %g) /* Second arg is location */\nfclamp( #, duration(ms), magnitude(mV)) ; clamp_resist = %g */\n", secname(sec),maxlevel, loc, clamp_resist);
56 #endif
57  for (i = 0; i < maxlevel; i++) {
58  Printf(" fclamp(%2d,%13g,%14g)\n", i, duration[i], vc[i]);
59  }
60 }
61 
62 void fclampv(void) {
63 
64  if (maxlevel) {
66  } else {
67  hoc_retpushx(0.);
68  }
69 }
70 
71 void fclampi(void) {
72  double v;
73 
74  if (maxlevel) {
75  v = clampval();
76  if (gtemp) {
77  hoc_retpushx(-(NODEV(pnd) - v) / clamp_resist);
78  } else {
79  hoc_retpushx(0.);
80  }
81  } else {
82  hoc_retpushx(0.);
83  }
84 }
85 
86 static void free_clamp(void);
87 
88 void fclamp(void) {
89  int i;
90 
91  if (nrn_nthread > 1) {
92  hoc_execerror("fsyn does not allow threads", "");
93  }
94  /* two args are maxlevel, loc */
95  /* three args are level, duration, vc */
96  i = chkarg(1, 0., 10000.);
97  if (ifarg(3)) {
98  int num;
99  if (i >= maxlevel) {
100  hoc_execerror("level index out of range", (char *) 0);
101  }
102  duration[i] = chkarg(2, 0., 1e21);
103  vc[i] = *getarg(3);
104 
105  tswitch[0] = -1e-9;
106  for (num = 0; num < maxlevel; num++) {
107  tswitch[num + 1] = tswitch[num] + duration[num];
108  }
109  oldsw = 0;
110  hoc_retpushx(tswitch[maxlevel - 1]);
111  } else {
112  free_clamp();
113  maxlevel = i;
114  if (maxlevel) {
115  duration = (double *) emalloc((unsigned) (maxlevel * sizeof(double)));
116  vc = (double *) emalloc((unsigned) (maxlevel * sizeof(double)));
117  tswitch = (double *) emalloc((unsigned) ((maxlevel + 1) * sizeof(double)));
118  for (i = 0; i < maxlevel; i++) {
119  duration[i] = 0.;
120  vc[i] = 0.;
121  tswitch[i] = -1e-9;
122  }
123  tswitch[maxlevel] = -1e-9;
124  loc = chkarg(2, 0., 1.);
125  sec = chk_access();
126  section_ref(sec);
127  clamp_prepare();
128  }
129  }
130  hoc_retpushx(0.);
131 }
132 
133 static void free_clamp(void) {
134  if (maxlevel) {
135  free((char *) duration);
136  free((char *) vc);
137  free((char *) tswitch);
138  maxlevel = 0;
139  section_unref(sec);
140  sec = 0;
141  }
142 }
143 
144 void clamp_prepare(void) /*fill in the section info*/
145 {
146  double area;
147 
148  if (!maxlevel) {
149  return;
150  }
151  if (sec->prop) {
152  pnd = node_ptr(sec, loc, &area);
153  } else {
154  free_clamp();
155  return;
156  }
157  if (clamp_resist <= 0) {
158  hoc_execerror("clamp_resist must be > 0 in megohms", (char *) 0);
159  }
160 }
161 
162 void activclamp_rhs(void) {
163  double v;
164  if (!maxlevel) {
165  return;
166  }
167  v = clampval();
168 #if EXTRACELLULAR
169  if (pnd->extnode) {
170  NODERHS(pnd) += gtemp * (v - NODEV(pnd) - pnd->extnode->v[0]);
171  } else {
172  NODERHS(pnd) += gtemp * (v - NODEV(pnd));
173  }
174 
175 #else
176  NODERHS(pnd) += gtemp*(v - NODEV(pnd));
177 #endif
178 }
179 
180 void activclamp_lhs(void) {
181  double v;
182  if (!maxlevel) {
183  return;
184  }
185  NODED(pnd) += gtemp;
186 }
187 
188 static double clampval(void) {
189  gtemp = 1.e2 / clamp_resist / NODEAREA(pnd);
190  for (;;) {
191 #if CVODE
193 #endif
194  if (nt_t < tswitch[oldsw]) {
195  if (oldsw == 0) {
196  break;
197  }
198 #if CVODE
199 /* for cvode the other was inefficient since t is non-monotonic */
200  --oldsw;
201 #else
202  oldsw = 0;
203 #endif
204  } else {
205  if (nt_t < tswitch[oldsw + 1]) {
206  break;
207  } else {
208  if (++oldsw == maxlevel) {
209  --oldsw;
210  gtemp = 0.;
211  break;
212  }
213  }
214  }
215  }
216  return vc[oldsw];
217 }
218 
#define area
Definition: md1redef.h:5
#define Printf
Definition: model.h:252
double * v
Definition: section.h:195
void activclamp_rhs(void)
Definition: clamp.cpp:162
struct Prop * prop
Definition: section.h:62
void clamp_prepare()
Definition: clamp.cpp:144
#define NODEV(n)
Definition: section.h:114
static double clampval()
Definition: clamp.cpp:188
#define NODED(n)
Definition: section.h:103
static double * tswitch
Definition: clamp.cpp:37
void activclamp_lhs(void)
Definition: clamp.cpp:180
#define v
Definition: md1redef.h:4
#define e
Definition: passive0.cpp:24
double clamp_resist
Definition: init.cpp:123
int nrn_nthread
Definition: multicore.cpp:44
static double loc
Definition: clamp.cpp:32
NrnThread * nrn_threads
Definition: multicore.cpp:45
static double * vc
Definition: clamp.cpp:37
static int oldsw
Definition: clamp.cpp:38
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
static Node * pnd
Definition: clamp.cpp:33
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
at_time
Definition: extargs.h:1
void fclampv(void)
Definition: clamp.cpp:62
hoc_retpushx(1.0)
char * emalloc(unsigned n)
Definition: list.cpp:189
void print_clamp()
Definition: clamp.cpp:46
void fclamp(void)
Definition: clamp.cpp:88
int ifarg(int)
Definition: code.cpp:1562
static int maxlevel
Definition: clamp.cpp:36
void section_ref(Section *)
Definition: solve.cpp:563
#define NODERHS(n)
Definition: section.h:104
#define nt_t
Definition: clamp.cpp:44
static double gtemp
Definition: clamp.cpp:35
#define getarg
Definition: hocdec.h:15
static void free_clamp(void)
Definition: clamp.cpp:133
#define i
Definition: md1redef.h:12
Node * node_ptr(Section *sec, double x, double *parea)
Definition: cabcode.cpp:2003
void section_unref(Section *)
Definition: solve.cpp:552
Definition: section.h:132
static Section * sec
Definition: clamp.cpp:34
void fclampi(void)
Definition: clamp.cpp:71
Section * chk_access(void)
Definition: cabcode.cpp:437
double chkarg(int, double low, double high)
Definition: code2.cpp:608
static double * duration
Definition: clamp.cpp:37
struct Extnode * extnode
Definition: section.h:160
#define NODEAREA(n)
Definition: section.h:115