file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/heccer/vm.h (Wed Jul 2 16:12:15 2008
) HOME
1: //
2: // Heccer : a compartmental solver that implements efficient Crank-Nicolson
3: // integration for neuronal models.
4: //
5:
6: //////////////////////////////////////////////////////////////////////////////
7: //'
8: //' Heccer : testbed C implementation
9: //'
10: //' Copyright (C) 2006-2008 Hugo Cornelis
11: //'
12: //' functional ideas .. Hugo Cornelis, hugo.cornelis@gmail.com
13: //'
14: //' coding ............ Hugo Cornelis, hugo.cornelis@gmail.com
15: //'
16: //////////////////////////////////////////////////////////////////////////////
17:
18:
19: #ifndef HECCER_VM_H
20: #define HECCER_VM_H
21:
22:
23: #include <stdio.h>
24:
25:
26: struct VM;
27:
28:
29: #ifndef TRUE
30: #define TRUE 1
31: #endif
32: #ifndef FALSE
33: #define FALSE 0
34: #endif
35:
36:
37: #include "callout.h"
38: #include "mechanism.h"
39:
40:
41: typedef union
42: {
43: //m index into mathcomponents
44:
45: int iMat;
46:
47: //m direct value
48:
49: double *pdValue;
50:
51: }
52: uMC2Mat;
53:
54: //s vm related (name subject to change)
55:
56: struct VM
57: {
58: //m compartment operations
59:
60: int iCops;
61:
62: int *piCops;
63:
64: //m compartment data
65:
66: int iDiagonals;
67:
68: double *pdDiagonals;
69:
70: int iAxres;
71:
72: double *pdAxres;
73:
74: //m results
75:
76: int iResults;
77:
78: double *pdResults;
79:
80: //t pdVm is accessible from outside, so should be moved to a
81: //t separate place ?
82: //t will become clear when addressing gets in place.
83:
84: int iVms;
85:
86: double *pdVms;
87:
88: //m math component number to mat number convertor
89:
90: //! note that this one does not index compartments, only the mechanism math components.
91:
92: uMC2Mat *piMC2Mat;
93:
94: //m math component number to mop number convertor
95:
96: int *piMC2Mop;
97:
98: //m mechanism operations
99:
100: int iMopNumber;
101:
102: int iMops;
103:
104: void *pvMops;
105:
106: //m mechanism addressables
107:
108: //t same as for pdVms applies, see above.
109:
110: int iMatNumber;
111:
112: int iMats;
113:
114: void *pvMats;
115:
116: //m indexing from mops or mats number towards one of the above
117:
118: void **ppvCMatsIndex;
119:
120: void **ppvMopsIndex;
121:
122: void **ppvMatsIndex;
123:
124: //m aggregate currents etc.
125:
126: int iAggregators;
127:
128: double *pdAggregators;
129:
130: /* //m fluxes link channels and pools */
131:
132: /* int iFluxes; */
133:
134: /* double *pdFluxes; */
135:
136: /* //m concentrations link pools and channels */
137:
138: /* int iConcentrations; */
139:
140: /* double **ppdConcentrations; */
141: };
142:
143:
144: #define SETMOP_FINISH(ppvMopsIndex,iMopNumber,pvMops,iMops) \
145: ((pvMops) \
146: ? ({ \
147: ((int *)pvMops)[0] = HECCER_MOP_FINISH; \
148: ppvMopsIndex[iMopNumber++] = pvMops; \
149: (pvMops) = (void *)&((int *)pvMops)[1]; \
150: 1; \
151: }) \
152: : ( \
153: (ppvMopsIndex) \
154: ? ({ \
155: iMopNumber++; \
156: (iMops) += sizeof(int); \
157: 1; \
158: }) \
159: : ({ iMopNumber++; 1; }) ) )
160:
161: //t can be automated by taking an array and diffing casted to char *
162: //t pointers to sequent entries ?
163:
164: #define ALIGNER8(s) ((((sizeof(s) - 1) >> 3) + 1) << 3)
165:
166: #define ALIGNER4(s) ((((sizeof(s) - 1) >> 3) + 1) << 2)
167:
168: //d mats are aligned to 8 bytes
169:
170: #define MAT_ALIGNER ALIGNER8
171:
172:
173: struct MatsCompartment
174: {
175: double dLeak;
176: double dInjected;
177: double dCapacity;
178: double dDiagonal;
179: };
180:
181:
182: #define SETMOP_COMPARTMENT(ppvMopsIndex,iMopNumber,pvMops,iMops) \
183: ((pvMops) \
184: ? ({ \
185: ((int *)pvMops)[0] = HECCER_MOP_COMPARTMENT; \
186: ppvMopsIndex[iMopNumber++] = pvMops; \
187: (pvMops) = (void *)&((int *)pvMops)[1]; \
188: 1; \
189: }) \
190: : ( \
191: (ppvMopsIndex) \
192: ? ({ \
193: iMopNumber++; \
194: (iMops) += sizeof(int); \
195: 1; \
196: }) \
197: : ({ iMopNumber++; 1; }) ) )
198:
199: #define SETMAT_COMPARTMENT(ppvCMatsIndex,iCNumber,ppvMatsIndex,iMatNumber,pvMats,iMats,dL,dI,dC,dD) \
200: ((pvMats) \
201: ? ({ struct MatsCompartment *pmats = (struct MatsCompartment *)pvMats ; \
202: pmats->dLeak = (dL) ; pmats->dInjected = (dI) ; \
203: pmats->dCapacity = (dC) ; \
204: pmats->dDiagonal = (dD) ; \
205: ppvCMatsIndex[iCNumber] = pvMats; \
206: ppvMatsIndex[iMatNumber++] = pvMats; \
207: pvMats = (void *)&((struct MatsCompartment *)pvMats)[1] ; \
208: 1 ; \
209: }) \
210: : ( \
211: (ppvMatsIndex) \
212: ? ({ \
213: iMatNumber++; \
214: (iMats) += MAT_ALIGNER(struct MatsCompartment); \
215: 1; \
216: }) \
217: : ({ iMatNumber++; 1; }) ) )
218:
219:
220: struct MopsSpringMass
221: {
222: //m operator : HECCER_MOP_TRIPLEEXPONENTIAL
223:
224: int iOperator;
225:
226: //m time table next event
227:
228: int iEvent;
229:
230: double *pdEvents;
231:
232: //m discrete event mapper indices, -1 for none
233:
234: int iDiscreteTarget;
235:
236: //m index into sm tables
237:
238: int iTable;
239:
240: //m random activation frequency
241:
242: double dFrequency;
243: };
244:
245: struct MatsSpringMass
246: {
247: //m time to next event from source
248:
249: double dNextEvent;
250:
251: //m two activation values
252:
253: double dX;
254: double dY;
255: /* double dZ; */
256: };
257:
258: #define SETMOP_SPRINGMASS(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,pdE,iDT,iT,dF) \
259: ((pvMops) \
260: ? ({ struct MopsSpringMass *pmops = (struct MopsSpringMass *)(pvMops); \
261: pmops->iOperator = HECCER_MOP_SPRINGMASS; \
262: pmops->iEvent = (pdE) == NULL ? -1 : 0 ; \
263: pmops->pdEvents = (pdE) ; \
264: pmops->iDiscreteTarget = (iDT) ; \
265: pmops->iTable = (iT) ; \
266: pmops->dFrequency = (dF) ; \
267: ppvMopsIndex[iMopNumber++] = pvMops; \
268: (pvMops) = (void *)&pmops[1]; \
269: 1; \
270: }) : ( \
271: (ppvMopsIndex) \
272: ? ({ \
273: piMC2Mop[iMathComponent] = iMopNumber++; \
274: (iMops) += sizeof(struct MopsSpringMass); \
275: 1; \
276: }) \
277: : ({ iMopNumber++; 1; }) ) )
278:
279: #define SETMAT_SPRINGMASS(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dInitX,dInitY,dNE) \
280: ((pvMats) \
281: ? ({ struct MatsSpringMass *pmats = (struct MatsSpringMass *)pvMats ; \
282: pmats->dX = (dInitX) ; \
283: pmats->dY = (dInitY) ; \
284: pmats->dNextEvent = (dNE) ; \
285: ppvMatsIndex[iMatNumber++] = pvMats; \
286: pvMats = (void *)&((struct MatsSpringMass *)pvMats)[1] ; \
287: 1; \
288: }) \
289: : ( \
290: (ppvMatsIndex) \
291: ? ({ \
292: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
293: (iMats) += MAT_ALIGNER(struct MatsSpringMass); \
294: 1; \
295: }) \
296: : ({ iMatNumber++; 1; }) ) )
297:
298:
299: struct MopsEventGenerate
300: {
301: //m operator : HECCER_MOP_EVENTGENERATOR
302:
303: int iOperator;
304:
305: //m source, sentinel for membrane potential
306:
307: uMC2Mat uSource;
308:
309: //m threshold logic
310:
311: double dThreshold;
312:
313: double dRefractoryReset;
314:
315: //m index into target tables
316:
317: int iTable;
318: };
319:
320: struct MatsEventGenerate
321: {
322: //m refractory counter, negative means not in refractory period
323:
324: double dRefractory;
325:
326: //m spiking or not
327:
328: double dSpike;
329: };
330:
331: #define SETMOP_EVENTGENERATE(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,iS,dT,dR,iT) \
332: ((pvMops) \
333: ? ({ struct MopsEventGenerate *pmops = (struct MopsEventGenerate *)(pvMops); \
334: pmops->iOperator = HECCER_MOP_EVENTGENERATE; \
335: pmops->uSource.iMat = (iS) ; \
336: pmops->dThreshold = (dT) ; \
337: pmops->dRefractoryReset = (dR) ; \
338: pmops->iTable = (iT) ; \
339: ppvMopsIndex[iMopNumber++] = pvMops; \
340: (pvMops) = (void *)&pmops[1]; \
341: 1; \
342: }) : ( \
343: (ppvMopsIndex) \
344: ? ({ \
345: piMC2Mop[iMathComponent] = iMopNumber++; \
346: (iMops) += sizeof(struct MopsEventGenerate); \
347: 1; \
348: }) \
349: : ({ iMopNumber++; 1; }) ) )
350:
351: #define SETMAT_EVENTGENERATE(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dR,dS) \
352: ((pvMats) \
353: ? ({ struct MatsEventGenerate *pmats = (struct MatsEventGenerate *)pvMats ; \
354: pmats->dRefractory = (dR) ; \
355: pmats->dSpike = (dS) ; \
356: ppvMatsIndex[iMatNumber++] = pvMats; \
357: pvMats = (void *)&((struct MatsEventGenerate *)pvMats)[1] ; \
358: 1; \
359: }) \
360: : ( \
361: (ppvMatsIndex) \
362: ? ({ \
363: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
364: (iMats) += MAT_ALIGNER(struct MatsEventGenerate); \
365: 1; \
366: }) \
367: : ({ iMatNumber++; 1; }) ) )
368:
369: struct MopsReset
370: {
371: //m operator : HECCER_MOP_RESET
372:
373: int iOperator;
374:
375: //m reset value
376:
377: double dReset;
378: };
379:
380: #define SETMOP_RESET(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,dR) \
381: ((pvMops) \
382: ? ({ struct MopsReset *pmops = (struct MopsReset *)(pvMops); \
383: pmops->iOperator = HECCER_MOP_RESET; \
384: pmops->dReset = (dR) ; \
385: ppvMopsIndex[iMopNumber++] = pvMops; \
386: (pvMops) = (void *)&pmops[1]; \
387: 1; \
388: }) : ( \
389: (ppvMopsIndex) \
390: ? ({ \
391: piMC2Mop[iMathComponent] = iMopNumber++; \
392: (iMops) += sizeof(struct MopsReset); \
393: 1; \
394: }) \
395: : ({ iMopNumber++; 1; }) ) )
396:
397:
398: struct MatsCallout
399: {
400: /* double d; */
401:
402: /* //m the external solver (or glue to) */
403:
404: /* ExternalFunction *pfCall; */
405:
406: //m currently points to intermediary
407:
408: struct Callout *pco;
409: };
410:
411: #define SETMOP_CALLOUT(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
412: ((pvMops) \
413: ? ({ ((int *)pvMops)[0] = HECCER_MOP_CALLOUT; \
414: ppvMopsIndex[iMopNumber++] = pvMops; \
415: (pvMops) = (void *)&((int *)pvMops)[1]; \
416: 1; \
417: }) \
418: : ( \
419: (ppvMopsIndex) \
420: ? ({ \
421: piMC2Mop[iMathComponent] = iMopNumber++; \
422: (iMops) += sizeof(int); \
423: 1; \
424: }) \
425: : ({ iMopNumber++; 1; }) ) )
426:
427: #define SETMAT_CALLOUT(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,p) \
428: ((pvMats) \
429: ? ({ struct MatsCallout *pmats = (struct MatsCallout *)pvMats ; \
430: pmats->pco = (p) ; \
431: ppvMatsIndex[iMatNumber++] = pvMats; \
432: pvMats = (void *)&((struct MatsCallout *)pvMats)[1] ; \
433: 1 ; \
434: }) \
435: : ( \
436: (ppvMatsIndex) \
437: ? ({ \
438: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
439: (iMats) += MAT_ALIGNER(struct MatsCallout); \
440: 1; \
441: }) \
442: : ({ iMatNumber++; 1; }) ) )
443:
444:
445: struct MopsInternalNernst
446: {
447: //m operator : HECCER_MOP_INTERNALNERNST
448:
449: int iOperator;
450:
451: //m constant
452:
453: double dConstant;
454:
455: //m external concentration
456:
457: double dExternal;
458:
459: //m variable internal concentration
460:
461: uMC2Mat uInternal;
462: };
463:
464:
465: struct MatsInternalNernst
466: {
467: //m nernst potential
468:
469: double dPotential;
470: };
471:
472: #define SETMOP_INTERNALNERNST(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,dC,dE,iI) \
473: ((pvMops) \
474: ? ({ struct MopsInternalNernst *pmops = (struct MopsInternalNernst *)(pvMops); \
475: pmops->iOperator = HECCER_MOP_INTERNALNERNST; \
476: pmops->dConstant = (dC) ; \
477: pmops->dExternal = (dE) ; \
478: pmops->uInternal.iMat = (iI) ; \
479: ppvMopsIndex[iMopNumber++] = pvMops; \
480: (pvMops) = (void *)&pmops[1]; \
481: 1; \
482: }) : ( \
483: (ppvMopsIndex) \
484: ? ({ \
485: piMC2Mop[iMathComponent] = iMopNumber++; \
486: (iMops) += sizeof(struct MopsInternalNernst); \
487: 1; \
488: }) \
489: : ({ iMopNumber++; 1; }) ) )
490:
491: #define SETMAT_INTERNALNERNST(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dP) \
492: ((pvMats) \
493: ? ({ struct MatsInternalNernst *pmats = (struct MatsInternalNernst *)pvMats ; \
494: pmats->dPotential = (dP) ; \
495: ppvMatsIndex[iMatNumber++] = pvMats; \
496: pvMats = (void *)&((struct MatsInternalNernst *)pvMats)[1] ; \
497: 1; \
498: }) \
499: : ( \
500: (ppvMatsIndex) \
501: ? ({ \
502: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
503: (iMats) += MAT_ALIGNER(struct MatsInternalNernst); \
504: 1; \
505: }) \
506: : ({ iMatNumber++; 1; }) ) )
507:
508:
509: struct MopsInitializeChannel
510: {
511: //m operation : HECCER_MOP_INITIALIZECHANNEL
512:
513: int iOperator;
514:
515: //m constant reversal potential
516:
517: double dReversalPotential;
518:
519: //m maximal channel conductance
520:
521: double dMaximalConductance;
522: };
523:
524:
525: #define SETMOP_INITIALIZECHANNEL(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,dG,dE) \
526: ((pvMops) \
527: ? ({ struct MopsInitializeChannel *pmops = (struct MopsInitializeChannel *)(pvMops); \
528: pmops->iOperator = HECCER_MOP_INITIALIZECHANNEL; \
529: pmops->dReversalPotential = (dE) ; \
530: pmops->dMaximalConductance = (dG) ; \
531: ppvMopsIndex[iMopNumber++] = pvMops; \
532: (pvMops) = (void *)&pmops[1]; \
533: 1; \
534: }) \
535: : ( \
536: (ppvMopsIndex) \
537: ? ({ \
538: piMC2Mop[iMathComponent] = iMopNumber++; \
539: (iMops) += sizeof(struct MopsInitializeChannel); \
540: 1; \
541: }) \
542: : ({ iMopNumber++; 1; }) ) )
543:
544:
545: struct MopsInitializeChannelErev
546: {
547: //m operation : HECCER_MOP_INITIALIZECHANNELEK
548:
549: int iOperator;
550:
551: //m variable reversal potential
552:
553: uMC2Mat uReversalPotential;
554:
555: //m maximal channel conductance
556:
557: double dMaximalConductance;
558: };
559:
560:
561: #define SETMOP_INITIALIZECHANNELEK(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,dG,iE) \
562: ((pvMops) \
563: ? ({ struct MopsInitializeChannelErev *pmops = (struct MopsInitializeChannelErev *)(pvMops); \
564: pmops->iOperator = HECCER_MOP_INITIALIZECHANNELEREV; \
565: pmops->uReversalPotential.iMat = (iE) ; \
566: pmops->dMaximalConductance = (dG) ; \
567: ppvMopsIndex[iMopNumber++] = pvMops; \
568: (pvMops) = (void *)&pmops[1]; \
569: 1; \
570: }) \
571: : ( \
572: (ppvMopsIndex) \
573: ? ({ \
574: piMC2Mop[iMathComponent] = iMopNumber++; \
575: (iMops) += sizeof(struct MopsInitializeChannelErev); \
576: 1; \
577: }) \
578: : ({ iMopNumber++; 1; }) ) )
579:
580:
581: struct MopsStoreChannelConductance
582: {
583: //m operator : HECCER_MOP_STORECHANNELCONDUCTANCE
584:
585: int iOperator;
586: };
587:
588: //t needs to be renamed to MatsStoreChannelConductance
589:
590: struct MatsStoreChannelConductance
591: {
592: //m single channel conductance
593:
594: double dChannelConductance;
595: };
596:
597: #define SETMOP_STORECHANNELCONDUCTANCE(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
598: ((pvMops) \
599: ? ({ struct MopsStoreChannelConductance *pmops = (struct MopsStoreChannelConductance *)(pvMops); \
600: pmops->iOperator = HECCER_MOP_STORECHANNELCONDUCTANCE ; \
601: ppvMopsIndex[iMopNumber++] = pvMops; \
602: (pvMops) = (void *)&pmops[1]; \
603: 1; \
604: }) : ( \
605: (ppvMopsIndex) \
606: ? ({ \
607: piMC2Mop[iMathComponent] = iMopNumber++; \
608: (iMops) += sizeof(struct MopsStoreChannelConductance); \
609: 1; \
610: }) \
611: : ({ iMopNumber++; 1; }) ) )
612:
613:
614: struct MopsVoltageTableDependency
615: {
616: //t so in principle the following operation is only needed once
617: //t per compartment. Still have to figure out how.
618:
619: //m operator : HECCER_MOP_LOADVOLTAGETABLE
620:
621: int iOperator;
622: };
623:
624: #define SETMOP_LOADVOLTAGETABLE(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
625: ((pvMops) \
626: ? ({ struct MopsVoltageTableDependency *pmops = (struct MopsVoltageTableDependency *)(pvMops); \
627: pmops->iOperator = HECCER_MOP_LOADVOLTAGETABLE ; \
628: ppvMopsIndex[iMopNumber++] = pvMops; \
629: (pvMops) = (void *)&pmops[1]; \
630: 1; \
631: }) : ( \
632: (ppvMopsIndex) \
633: ? ({ \
634: piMC2Mop[iMathComponent] = iMopNumber++; \
635: (iMops) += sizeof(struct MopsVoltageTableDependency); \
636: 1; \
637: }) \
638: : ({ iMopNumber++; 1; }) ) )
639:
640:
641: struct MopsUpdateCompartmentCurrent
642: {
643: //m operator : HECCER_MOP_UPDATECOMPARTMENTCURRENT
644:
645: int iOperator;
646: };
647:
648: #define SETMOP_UPDATECOMPARTMENTCURRENT(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
649: ((pvMops) \
650: ? ({ struct MopsUpdateCompartmentCurrent *pmops = (struct MopsUpdateCompartmentCurrent *)(pvMops); \
651: pmops->iOperator = HECCER_MOP_UPDATECOMPARTMENTCURRENT ; \
652: ppvMopsIndex[iMopNumber++] = pvMops; \
653: (pvMops) = (void *)&pmops[1]; \
654: 1; \
655: }) : ( \
656: (ppvMopsIndex) \
657: ? ({ \
658: piMC2Mop[iMathComponent] = iMopNumber++; \
659: (iMops) += sizeof(struct MopsUpdateCompartmentCurrent); \
660: 1; \
661: }) \
662: : ({ iMopNumber++; 1; }) ) )
663:
664:
665: struct MopsSingleGateConcept
666: {
667: //m operator : HECCER_MOP_CONCEPTGATE
668:
669: int iOperator;
670:
671: //m table index
672:
673: int iTableIndex;
674:
675: //m power to apply
676:
677: int iPower;
678:
679: //m possibly solved dependence
680:
681: uMC2Mat uState;
682: };
683:
684: #define SETMOP_POWEREDGATECONCEPT(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,iT,iP,iS) \
685: ((pvMops) \
686: ? ({ struct MopsSingleGateConcept *pmops = (struct MopsSingleGateConcept *)(pvMops); \
687: pmops->iOperator = HECCER_MOP_CONCEPTGATE ; \
688: pmops->iTableIndex = (iT) ; \
689: pmops->iPower = (iP) ; \
690: pmops->uState.iMat = (iS) ; \
691: ppvMopsIndex[iMopNumber++] = pvMops; \
692: ((iP) <= 0) \
693: ? ({ \
694: HeccerError \
695: (pheccer, \
696: NULL, \
697: "gate power %i out of range", \
698: (iP)); \
699: }) \
700: : ({ }); \
701: (pvMops) = (void *)&pmops[1]; \
702: 1; \
703: }) : ( \
704: (ppvMopsIndex) \
705: ? ({ \
706: piMC2Mop[iMathComponent] = iMopNumber++; \
707: (iMops) += sizeof(struct MopsSingleGateConcept); \
708: 1; \
709: }) \
710: : ({ iMopNumber++; 1; }) ) )
711:
712:
713: struct MatsSingleGateConcept
714: {
715: //m gate activation
716:
717: double dActivation;
718: };
719:
720: #define SETMAT_POWEREDGATECONCEPT(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dA) \
721: ((pvMats) \
722: ? ({ struct MatsSingleGateConcept *pmats = (struct MatsSingleGateConcept *)pvMats ; \
723: pmats->dActivation = (dA) ; \
724: ppvMatsIndex[iMatNumber++] = pvMats; \
725: pvMats = (void *)&((struct MatsSingleGateConcept *)pvMats)[1] ; \
726: 1 ; \
727: }) \
728: : ( \
729: (ppvMatsIndex) \
730: ? ({ \
731: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
732: (iMats) += MAT_ALIGNER(struct MatsSingleGateConcept); \
733: 1; \
734: }) \
735: : ({ iMatNumber++; 1; }) ) )
736:
737:
738: struct MopsExponentialDecay
739: {
740: //m operator : HECCER_MOP_EXPONENTIALDECAY
741:
742: int iOperator;
743:
744: //m beta
745:
746: double dBeta;
747:
748: //m steady state
749:
750: double dSteadyState;
751:
752: //m tau
753:
754: double dTau;
755:
756: //m possibly solved external flux contribution
757:
758: uMC2Mat puExternal[EXPONENTIALDECAY_CONTRIBUTORS];
759: };
760:
761:
762: struct MatsExponentialDecay
763: {
764: //m resulting state
765:
766: double dState;
767: };
768:
769: #define SETMOP_EXPONENTIALDECAY(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,dB,dS,dT,piE) \
770: ((pvMops) \
771: ? ({ struct MopsExponentialDecay *pmops = (struct MopsExponentialDecay *)(pvMops); \
772: pmops->iOperator = HECCER_MOP_EXPONENTIALDECAY; \
773: pmops->dBeta = (dB) ; \
774: pmops->dSteadyState = (dS) ; \
775: pmops->dTau = (dT) ; \
776: int i; \
777: for (i = 0 ; i < EXPONENTIALDECAY_CONTRIBUTORS ; i++) \
778: { \
779: pmops->puExternal[i].iMat = (piE)[i] ; \
780: } \
781: ppvMopsIndex[iMopNumber++] = pvMops; \
782: (pvMops) = (void *)&pmops[1]; \
783: 1; \
784: }) : ( \
785: (ppvMopsIndex) \
786: ? ({ \
787: piMC2Mop[iMathComponent] = iMopNumber++; \
788: (iMops) += sizeof(struct MopsExponentialDecay); \
789: 1; \
790: }) \
791: : ({ iMopNumber++; 1; }) ) )
792:
793: #define SETMAT_EXPONENTIALDECAY(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dS) \
794: ((pvMats) \
795: ? ({ struct MatsExponentialDecay *pmats = (struct MatsExponentialDecay *)pvMats ; \
796: pmats->dState = (dS) ; \
797: ppvMatsIndex[iMatNumber++] = pvMats; \
798: pvMats = (void *)&((struct MatsExponentialDecay *)pvMats)[1] ; \
799: 1; \
800: }) \
801: : ( \
802: (ppvMatsIndex) \
803: ? ({ \
804: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
805: (iMats) += MAT_ALIGNER(struct MatsExponentialDecay); \
806: 1; \
807: }) \
808: : ({ iMatNumber++; 1; }) ) )
809:
810:
811: struct MopsFluxPool
812: {
813: //m operator : HECCER_MOP_FLUXPOOL
814:
815: int iOperator;
816:
817: /* //m pool index */
818:
819: /* int iPool; */
820: };
821:
822: struct MatsFluxPool
823: {
824: //m resulting flux
825:
826: double dFlux;
827: };
828:
829: #define SETMOP_FLUXPOOL(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops/* ,iP */) \
830: ((pvMops) \
831: ? ({ struct MopsFluxPool *pmops = (struct MopsFluxPool *)(pvMops); \
832: pmops->iOperator = HECCER_MOP_FLUXPOOL; \
833: /* pmops->iPool = (iP) ; */ \
834: ppvMopsIndex[iMopNumber++] = pvMops; \
835: (pvMops) = (void *)&pmops[1]; \
836: 1; \
837: }) : ( \
838: (ppvMopsIndex) \
839: ? ({ \
840: piMC2Mop[iMathComponent] = iMopNumber++; \
841: (iMops) += sizeof(struct MopsFluxPool); \
842: 1; \
843: }) \
844: : ({ iMopNumber++; 1; }) ) )
845:
846: #define SETMAT_FLUXPOOL(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dF) \
847: ((pvMats) \
848: ? ({ struct MatsFluxPool *pmats = (struct MatsFluxPool *)pvMats ; \
849: pmats->dFlux = (dF) ; \
850: ppvMatsIndex[iMatNumber++] = pvMats; \
851: pvMats = (void *)&((struct MatsFluxPool *)pvMats)[1] ; \
852: 1; \
853: }) : ( \
854: (ppvMatsIndex) \
855: ? ({ \
856: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
857: (iMats) += MAT_ALIGNER(struct MatsFluxPool); \
858: 1; \
859: }) \
860: : ({ iMatNumber++; 1; }) ) )
861:
862:
863: struct MopsRegisterChannelCurrent
864: {
865: //m operator : HECCER_MOP_REGISTERCHANNELCURRENT
866:
867: int iOperator;
868: };
869:
870: #define SETMOP_REGISTERCHANNELCURRENT(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
871: ((pvMops) \
872: ? ({ struct MopsRegisterChannelCurrent *pmops = (struct MopsRegisterChannelCurrent *)(pvMops); \
873: pmops->iOperator = HECCER_MOP_REGISTERCHANNELCURRENT ; \
874: ppvMopsIndex[iMopNumber++] = pvMops; \
875: (pvMops) = (void *)&pmops[1]; \
876: 1; \
877: }) : ( \
878: (ppvMopsIndex) \
879: ? ({ \
880: piMC2Mop[iMathComponent] = iMopNumber++; \
881: (iMops) += sizeof(struct MopsRegisterChannelCurrent); \
882: 1; \
883: }) \
884: : ({ iMopNumber++; 1; }) ) )
885:
886:
887: struct MopsStoreSingleChannelCurrent
888: {
889: //m operator : HECCER_MOP_STORESINGLECHANNELCURRENT
890:
891: int iOperator;
892: };
893:
894: struct MatsStoreSingleChannelCurrent
895: {
896: //m single channel conductance
897:
898: double dConductance;
899:
900: //m single channel current
901:
902: double dCurrent;
903:
904: };
905:
906: #define SETMOP_STORESINGLECHANNELCURRENT(iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops) \
907: ((pvMops) \
908: ? ({ struct MopsStoreSingleChannelCurrent *pmops = (struct MopsStoreSingleChannelCurrent *)(pvMops); \
909: pmops->iOperator = HECCER_MOP_STORESINGLECHANNELCURRENT ; \
910: ppvMopsIndex[iMopNumber++] = pvMops; \
911: (pvMops) = (void *)&pmops[1]; \
912: 1; \
913: }) : ( \
914: (ppvMopsIndex) \
915: ? ({ \
916: piMC2Mop[iMathComponent] = iMopNumber++; \
917: (iMops) += sizeof(struct MopsStoreSingleChannelCurrent); \
918: 1; \
919: }) \
920: : ({ iMopNumber++; 1; }) ) )
921:
922: #define SETMAT_STORESINGLECHANNELCURRENT(iMathComponent,piMC2Mat,ppvMatsIndex,iMatNumber,pvMats,iMats,dCo,dCu) \
923: ((pvMats) \
924: ? ({ struct MatsStoreSingleChannelCurrent *pmats = (struct MatsStoreSingleChannelCurrent *)pvMats ; \
925: pmats->dConductance = (dCo) ; \
926: pmats->dCurrent = (dCu) ; \
927: ppvMatsIndex[iMatNumber++] = pvMats; \
928: pvMats = (void *)&((struct MatsStoreSingleChannelCurrent *)pvMats)[1] ; \
929: 1; \
930: }) : ( \
931: (ppvMatsIndex) \
932: ? ({ \
933: piMC2Mat[iMathComponent].iMat = iMatNumber++; \
934: (iMats) += MAT_ALIGNER(struct MatsStoreSingleChannelCurrent); \
935: 1; \
936: }) \
937: : ({ iMatNumber++; 1; }) ) )
938:
939:
940: struct MopsAggregateCurrent
941: {
942: //m operator : HECCER_MOP_AGGREGATECURRENT
943:
944: int iOperator;
945:
946: //m index into the aggregate results array
947:
948: int iIndex;
949: };
950:
951: #define SET_AGGREGATOR_MAX(pvm,iAggregator) ((pvm)->iAggregators <= iAggregator ? ((pvm)->iAggregators = iAggregator + 1) : (0))
952:
953: #define SETMOP_AGGREGATECURRENT(pvm,iMathComponent,piMC2Mop,ppvMopsIndex,iMopNumber,pvMops,iMops,iAggregator) \
954: ((pvMops) \
955: ? ({ struct MopsAggregateCurrent *pmops = (struct MopsAggregateCurrent *)(pvMops); \
956: pmops->iOperator = HECCER_MOP_AGGREGATECURRENT ; \
957: pmops->iIndex = iAggregator ; \
958: ppvMopsIndex[iMopNumber++] = pvMops; \
959: (pvMops) = (void *)&pmops[1]; \
960: SET_AGGREGATOR_MAX((pvm),(iAggregator)); \
961: 1; \
962: }) : ( \
963: (ppvMopsIndex) \
964: ? ({ \
965: piMC2Mop[iMathComponent] = iMopNumber++; \
966: (iMops) += sizeof(struct MopsAggregateCurrent); \
967: 1; \
968: }) \
969: : ({ iMopNumber++; 1; }) ) )
970:
971:
972: //d operations for compartments
973:
974: #define HECCER_COP_FORWARD_ELIMINATION 1
975: #define HECCER_COP_BACKWARD_SUBSTITUTION 2
976: #define HECCER_COP_FINISH_ROW 3
977: #define HECCER_COP_FINISH 4
978: #define HECCER_COP_SET_DIAGONAL 5
979: #define HECCER_COP_NEXT_ROW 6
980:
981: #define HECCER_COP_CN_FOBA_ELIMINATION ( 1 || 16 )
982: #define HECCER_COP_CN_CALC_RESULTS ( 2 || 16 )
983: #define HECCER_COP_CN_FINISH ( 3 || 16 )
984: #define HECCER_COP_CN_SET_DIAGONAL ( 4 || 16 )
985: #define HECCER_COP_CN_SKIP_DIAGONAL ( 5 || 16 )
986:
987: #define HECCER_COP_BE_FOBA_ELIMINATION ( 1 || 32 )
988: #define HECCER_COP_BE_CALC_RESULTS ( 2 || 32 )
989: #define HECCER_COP_BE_FINISH ( 3 || 32 )
990: #define HECCER_COP_BE_SET_DIAGONAL ( 4 || 32 )
991: #define HECCER_COP_BE_SKIP_DIAGONAL ( 5 || 32 )
992:
993:
994: //d operations for mechanisms
995:
996: #define HECCER_MOP_COMPARTMENT 1
997: #define HECCER_MOP_FINISH 2
998:
999: #define HECCER_MOP_CALLOUT 10
1000:
1001: #define HECCER_MOP_INITIALIZECHANNEL 20
1002: #define HECCER_MOP_LOADVOLTAGETABLE 21
1003: #define HECCER_MOP_CONCEPTGATE 22
1004: #define HECCER_MOP_STORECHANNELCONDUCTANCE 23
1005: #define HECCER_MOP_EXPONENTIALDECAY 24
1006: #define HECCER_MOP_FLUXPOOL 25
1007: #define HECCER_MOP_REGISTERCHANNELCURRENT 26
1008: #define HECCER_MOP_INTERNALNERNST 27
1009: #define HECCER_MOP_INITIALIZECHANNELEREV 28
1010: #define HECCER_MOP_SPRINGMASS 29
1011: #define HECCER_MOP_EVENTGENERATE 31
1012: #define HECCER_MOP_RESET 32
1013:
1014: #define HECCER_MOP_UPDATECOMPARTMENTCURRENT 40
1015: #define HECCER_MOP_STORESINGLECHANNELCURRENT 41
1016:
1017: #define HECCER_MOP_AGGREGATECURRENT 60
1018:
1019:
1020: //d all operators for mechanisms have an opcode larger than ...
1021:
1022: //t but perhaps this should be done using flags, not sure.
1023:
1024: #define HECCER_MOP_COMPARTMENT_BARRIER 9
1025:
1026:
1027: //f prototypes
1028:
1029: int
1030: HeccerVMDump
1031: (struct VM *pvm, FILE *pfile, int iSelection);
1032:
1033:
1034: #endif
1035:
1036:
1037:
Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008