NEURON
nrndae.h
Go to the documentation of this file.
1 /**
2  * @file nrndae.h
3  * @brief Supports modifying voltage equations and adding new equations.
4  * @author Michael Hines, Robert McDougal
5  *
6  * @remark Subclasses of NrnDAE can work with equations of the form
7  * \f[$C \frac{dy}{dt} = f(y)$\f]. LinearModelAddition, defined in linmod.h
8  * and linmod.cpp is an example that supports linear dynamics of the
9  * form \f[$C \frac{dy}{dt} = A y + b$\f].
10  */
11 
12 #ifndef nrndae_h
13 #define nrndae_h
14 // this defines things needed by ocmatrix
15 #include <OS/list.h>
16 
17 #include "ivocvect.h"
18 #include "matrixmap.h"
19 #include <list>
20 
21 /**
22  * NEURON Differential Algebraic Equations.
23  *
24  * @remark This is an abstract class; subclass this (or use a subclass) to
25  * add dynamics. LinearModelAddition is an example. See linmod.h.
26  */
27 class NrnDAE {
28 public:
29  /**
30  * Find the number of state variables introduced by this object.
31  *
32  * @return The number of states added (not modified) by this instance.
33  */
34  int extra_eqn_count();
35 
36  /**
37  * Allocate space for these dynamics in the overall system.
38  *
39  * @param start_index starting index for new states
40  */
41  void alloc(int start_index);
42 
43  /**
44  * Compute the left side portion of \f[$(C - J) \frac{dy}{dt} = f(y)$\f].
45  */
46  void lhs();
47 
48  /**
49  * Compute the right side portion of \f[$(C - J) \frac{dy}{dt} = f(y)$\f].
50  */
51  void rhs();
52 
53  /**
54  * Compute the residual: \f[$f(y) - C \frac{dy}{dt}$\f]
55  *
56  * @param y array of state variables
57  * @param yprime array of derivatives of state variables
58  * @param delta array to store the difference $f(y)-Cy'$
59  */
60  void dkres(double* y, double* yprime, double* delta);
61 
62  /**
63  * Initialize the dynamics.
64  *
65  * @remark Does this by calling f_init_. If f_init_ is NULL, initializes to
66  * values in y0_. If y0_ is NULL, initializes all states to 0.
67  */
68  void init();
69 
70  /**
71  * Update states to reflect the changes over a time-step.
72  *
73  * @remark When this function is called, the changes have already been
74  * computed by the solver. This just updates the local variables.
75  */
76  void update();
77 
78  /**
79  * Setup the map between voltages and states in y_.
80  *
81  * @param pv pointers to voltage nodes (set by this function)
82  * @param pvdot pointers to voltage derivatives (set by this
83  * function)
84  */
85  void dkmap(double** pv, double** pvdot);
86 
87  /**
88  * Destructor.
89  */
90  virtual ~NrnDAE();
91 
92 protected:
93  /**
94  * Constructor.
95  *
96  * @param cmat the matrix \f[$C$\f] in \f[$Cy'=f(y)$\f].
97  * @param yvec vector to store the state variables in
98  * @param y0 initial conditions
99  * @param nnode number of voltage equations to modify
100  * @param nodes pointers to voltage nodes
101  * @param elayer which potential layer to use for each voltage node
102  * @param f_init function to call during an finitialize
103  * @param data data to pass to f_init
104  *
105  * @remark If cmat is NULL, then assumes \f[$C$\f] is the identity matrix.
106  * @remark If f_init is non-NULL, that takes priority. Otherwise, if
107  * y0 is non-NULL, then initializes to those values. Otherwise
108  * initializes by setting all states to 0.
109  */
110  NrnDAE(Matrix* cmat, Vect* const yvec, Vect* const y0, int nnode,
111  Node** const nodes, Vect* const elayer,
112  void (*f_init)(void* data) = NULL, void* const data = NULL);
113 
114 private:
115  /**
116  * The right-hand-side function.
117  *
118  * @param y the state variables
119  * @param yprime a vector to store the derivatives
120  * @param size the number of state variables
121  */
122  virtual void f_(Vect& y, Vect& yprime, int size) = 0;
123 
124  /**
125  * Compute the Jacobian.
126  *
127  * @param y the state variables
128  * @return Pointer to a MatrixMap containing the jacobian.
129  *
130  * @remark The calling function will not delete this pointer.
131  * @remark It is occasionally easier to return the Jacobian divided by
132  * a constant factor. If so, have jacobian_multiplier_ return a
133  * number that should be multiplied by the matrix returned by
134  * this function to get the true Jacobian.
135  */
136  virtual MatrixMap* jacobian_(Vect& y) = 0;
137 
138  /// Function used for initializing the state variables.
139  void (*f_init_)(void* data);
140 
141  /// Data to pass to f_init_.
142  void* data_;
143 
144  // value of jacobian_ must be multiplied by this value before use
145  virtual double jacobian_multiplier_() {return 1;}
146 
147  /**
148  * Additional allocation for subclasses.
149  *
150  * @remark Called during alloc(). Unless overriden, this function is empty.
151  */
152  virtual void alloc_(int size, int start, int nnode, Node** nodes,
153  int* elayer);
154 
155  /// the matrix \f[$C$ in $C y' = f(y)$\f]
157 
158  /// identity matrix if constructed with \f[$C$\f] NULL; else NULL.
160 
161  /// vector of initial conditions
163 
164  /// vector to store the state variables in
166 
167  /// total number of states declared or modified in this object
168  int size_;
169 
170  /// mapping between the states in y and the states in the whole system
171  int* bmap_;
172 
173  /// Number of voltage nodes used by the dynamics.
174  int nnode_;
175 
176  /// Pointers to voltage nodes used by the dynamics.
178 
179  /// the position of the first added equation (if any) in the global system
180  int start_;
181 
182  /// temporary vector used for residual calculation.
184 
185  /// temporary vector used for residual calculation.
187 
188  /**
189  * Which voltage layers to read from.
190  *
191  * @remark Normally elements are 0 and refer to internal potential.
192  * Otherwise range from 1 to nlayer and refer to vext[elayer-1].
193  * vm+vext and vext must be placed in y for calculation of rhs
194  */
195  int* elayer_;
196 
197  /// Transfer any voltage states to y_.
198  void v2y();
199 };
200 
201 /**
202  * Add a NrnDAE object to the system.
203  *
204  * @param n The NrnDAE object (ie the dynamics) to add.
205  */
206 void nrndae_register(NrnDAE* n);
207 
208 /**
209  * Remove a NrnDAE object from the system.
210  *
211  * @param n The NrnDAE object (ie the dynamics) to remove.
212  */
213 void nrndae_deregister(NrnDAE* n);
214 
215 typedef std::list<NrnDAE*> NrnDAEPtrList;
216 typedef NrnDAEPtrList::const_iterator NrnDAEPtrListIterator;
217 
218 #endif
219 
#define data
Definition: rbtqueue.cpp:49
void init()
Initialize the dynamics.
Definition: nrndae.cpp:217
void dkres(double *y, double *yprime, double *delta)
Compute the residual: .
Definition: nrndae.cpp:259
void alloc(int start_index)
Allocate space for these dynamics in the overall system.
Definition: nrndae.cpp:103
#define Vect
Definition: ivocvect.h:14
Vect yptmp_
temporary vector used for residual calculation.
Definition: nrndae.h:186
Vect & y_
vector to store the state variables in
Definition: nrndae.h:165
void
void v2y()
Transfer any voltage states to y_.
Definition: nrndae.cpp:239
NrnDAEPtrList::const_iterator NrnDAEPtrListIterator
Definition: nrndae.h:216
MatrixMap * c_
the matrix
Definition: nrndae.h:156
void rhs()
Compute the right side portion of .
Definition: nrndae.cpp:287
Node ** nodes_
Pointers to voltage nodes used by the dynamics.
Definition: nrndae.h:177
virtual ~NrnDAE()
Destructor.
Definition: nrndae.cpp:175
j< sec-> nnode
Definition: treeset.cpp:905
void start()
Definition: hel2mos.cpp:205
void dkmap(double **pv, double **pvdot)
Setup the map between voltages and states in y_.
Definition: nrndae.cpp:196
int extra_eqn_count()
Find the number of state variables introduced by this object.
Definition: nrndae.cpp:190
int const size_t const size_t n
Definition: nrngsl.h:12
virtual void alloc_(int size, int start, int nnode, Node **nodes, int *elayer)
Additional allocation for subclasses.
Definition: nrndae.cpp:100
void nrndae_register(NrnDAE *n)
Add a NrnDAE object to the system.
Definition: nrndae.cpp:28
void * data_
Data to pass to f_init_.
Definition: nrndae.h:142
std::list< NrnDAE * > NrnDAEPtrList
Definition: nrndae.h:215
virtual void f_(Vect &y, Vect &yprime, int size)=0
The right-hand-side function.
virtual double jacobian_multiplier_()
Definition: nrndae.h:145
int nnode_
Number of voltage nodes used by the dynamics.
Definition: nrndae.h:174
int * bmap_
mapping between the states in y and the states in the whole system
Definition: nrndae.h:171
void nrndae_deregister(NrnDAE *n)
Remove a NrnDAE object from the system.
Definition: nrndae.cpp:32
void update()
Update states to reflect the changes over a time-step.
Definition: nrndae.cpp:206
Vect * y0_
vector of initial conditions
Definition: nrndae.h:162
NrnDAE(Matrix *cmat, Vect *const yvec, Vect *const y0, int nnode, Node **const nodes, Vect *const elayer, void(*f_init)(void *data)=NULL, void *const data=NULL)
Constructor.
Definition: nrndae.cpp:135
NEURON Differential Algebraic Equations.
Definition: nrndae.h:27
int start_
the position of the first added equation (if any) in the global system
Definition: nrndae.h:180
Vect cyp_
temporary vector used for residual calculation.
Definition: nrndae.h:183
int * elayer_
Which voltage layers to read from.
Definition: nrndae.h:195
virtual MatrixMap * jacobian_(Vect &y)=0
Compute the Jacobian.
static Symbol * pv[4]
Definition: partial.cpp:80
Matrix * assumed_identity_
identity matrix if constructed with NULL; else NULL.
Definition: nrndae.h:159
Definition: section.h:132
return NULL
Definition: cabcode.cpp:461
MatrixPtr Matrix
Definition: sputils.c:601
void(* f_init_)(void *data)
Function used for initializing the state variables.
Definition: nrndae.h:139
void lhs()
Compute the left side portion of .
Definition: nrndae.cpp:296
int size_
total number of states declared or modified in this object
Definition: nrndae.h:168