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  if (!maxlevel) {
192  return;
193  }
194  NODED(pnd) += gtemp;
195 }
196 
197 static double clampval(void) {
198  gtemp = 1.e2 / clamp_resist / NODEAREA(pnd);
199  for (;;) {
201  if (nt_t < tswitch[oldsw]) {
202  if (oldsw == 0) {
203  break;
204  }
205  /* for cvode the other was inefficient since t is non-monotonic */
206  --oldsw;
207  } else {
208  if (nt_t < tswitch[oldsw + 1]) {
209  break;
210  } else {
211  if (++oldsw == maxlevel) {
212  --oldsw;
213  gtemp = 0.;
214  break;
215  }
216  }
217  }
218  }
219  return vc[oldsw];
220 }
Section * chk_access()
Definition: cabcode.cpp:449
const char * secname(Section *sec)
name of section (for use in error messages)
Definition: cabcode.cpp:1674
Node * node_ptr(Section *sec, double x, double *parea)
Definition: cabcode.cpp:1828
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:197
void print_clamp()
Definition: clamp.cpp:46
static double * tswitch
Definition: clamp.cpp:37
#define area
Definition: md1redef.h:12
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
at_time
Definition: extargs.h:1
double chkarg(int, double low, double high)
Definition: code2.cpp:626
void hoc_retpushx(double x)
Definition: hocusr.cpp:154
#define getarg
Definition: hocdec.h:17
NrnThread * nrn_threads
Definition: multicore.cpp:56
int nrn_nthread
Definition: multicore.cpp:55
void hoc_execerror(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:39
static void * emalloc(size_t size)
Definition: mpispike.cpp:30
void section_ref(Section *)
Definition: solve.cpp:520
void section_unref(Section *)
Definition: solve.cpp:509
int ifarg(int)
Definition: code.cpp:1607
double clamp_resist
Definition: init.cpp:110
#define NODEAREA(n)
Definition: section.h:101
#define NODEV(n)
Definition: section_fwd.hpp:60
#define NODERHS(n)
Definition: section_fwd.hpp:55
#define NODED(n)
Definition: section_fwd.hpp:54
double * v
Definition: section_fwd.hpp:40
Definition: section.h:105
Extnode * extnode
Definition: section.h:199
Prop * prop
Definition: section.h:71
int Printf(const char *fmt, Args... args)
Definition: logger.hpp:18