001: //
002: // Heccer : a compartmental solver that implements efficient Crank-Nicolson
003: // integration for neuronal models.
004: //
005: 
006: //////////////////////////////////////////////////////////////////////////////
007: //'
008: //' Heccer : testbed C implementation
009: //'
010: //' Copyright (C) 2006-2008 Hugo Cornelis
011: //'
012: //' functional ideas ..   Hugo Cornelis, hugo.cornelis@gmail.com
013: //'
014: //' coding ............   Hugo Cornelis, hugo.cornelis@gmail.com
015: //'
016: //////////////////////////////////////////////////////////////////////////////
017: 
018: 
019: #include <stdlib.h>
020: 
021: #include "../../heccer/addressing.h"
022: #include "../../heccer/compartment.h"
023: #include "../../heccer/heccer.h"
024: 
025: 
026: #define HECCER_TEST_OPTIONS (HECCER_OPTION_ENABLE_AGGREGATORS | HECCER_OPTION_ENABLE_INDIVIDUAL_CURRENTS)
027: #define HECCER_TEST_TESTED_THINGS ( HECCER_DUMP_VM_COMPARTMENT_MATRIX \
028:                                     | HECCER_DUMP_VM_COMPARTMENT_MATRIX_DIAGONALS \
029:                                     | HECCER_DUMP_VM_COMPARTMENT_OPERATIONS \
030:                                     | HECCER_DUMP_VM_MECHANISM_DATA \
031:                                     | HECCER_DUMP_VM_MECHANISM_OPERATIONS \
032:                                     | HECCER_DUMP_VM_SUMMARY \
033:                                     | HECCER_DUMP_VM_AGGREGATORS \
034:         )
035: #define HECCER_TEST_TIME_STEP (6e-6)
036: 
037: 
038: struct Compartment pcomp[] =
039: {
040:     {
041:         //m administrative overhead
042: 
043:         {
044:             //m type of structure
045: 
046:             MATH_TYPE_Compartment,
047: 
048: #ifdef HECCER_SOURCE_NEUROSPACES
049: 
050:             //m identification
051: 
052:             ADDRESSING_NEUROSPACES_2_HECCER(1000),
053: 
054: #endif
055: 
056: #ifdef HECCER_SOURCE_TYPING
057: 
058:             //m model source type number
059: 
060:             //! source typing is used to compute aggregate currents ao
061:             //! things.
062: 
063:             -1,
064: 
065: #endif
066: 
067:         },
068: 
069:         //m index of parent compartment, -1 for none
070: 
071:         -1,
072: 
073: /* 	//m first mechanism */
074: 
075: /* 	NULL, */
076: 
077: /* 	//m number of mechanisms */
078: 
079: /* 	0, */
080: 
081:         //m descriptive values, alphabetical order
082: 
083: /*     double dCm; */
084: 
085:         4.57537e-11, // unscaled 0.0164,
086: 
087: /*     double dEm; */
088: 
089:         -0.08,
090: 
091: /*     double dInitVm; */
092: 
093:         -0.028,
094: 
095: /*     double dInject;		 */
096: 
097:         0,
098: 
099: /*     double dRa; */
100: 
101:         360502, // unscaled 2.5,
102: 
103: /*     double dRm; */
104: 
105:         3.58441e+08, // unscaled 1
106:     },
107: 
108:     {
109:         //m administrative overhead
110: 
111:         {
112:             //m type of structure
113: 
114:             MATH_TYPE_Compartment,
115: 
116: #ifdef HECCER_SOURCE_NEUROSPACES
117: 
118:             //m identification
119: 
120:             ADDRESSING_NEUROSPACES_2_HECCER(2000),
121: 
122: #endif
123: 
124: #ifdef HECCER_SOURCE_TYPING
125: 
126:             //m model source type number
127: 
128:             //! source typing is used to compute aggregate currents ao
129:             //! things.
130: 
131:             -1,
132: 
133: #endif
134: 
135:         },
136: 
137:         //m index of parent compartment, -1 for none
138: 
139:         0,
140: 
141: /* 	//m first mechanism */
142: 
143: /* 	NULL, */
144: 
145: /* 	//m number of mechanisms */
146: 
147: /* 	0, */
148: 
149:         //m descriptive values, alphabetical order
150: 
151: /*     double dCm; */
152: 
153:         5.755329373e-12, // unscaled 0.0164,
154: 
155: /*     double dEm; */
156: 
157:         -0.08,
158: 
159: /*     double dInitVm; */
160: 
161:         -0.068,
162: 
163: /*     double dInject;		 */
164: 
165:         0,
166: 
167: /*     double dRa; */
168: 
169:         772813.4375, // unscaled 2.5,
170: 
171: /*     double dRm; */
172: 
173:         8.548598272e9, // unscaled 3
174:     },
175: };
176: 
177: 
178: //v a simple fast sodium channel
179: 
180: struct ChannelActInact pcaiCaT[] =
181: {
182:     {
183:         //m administrative overhead
184: 
185:         {
186:             //m type of structure
187: 
188:             MATH_TYPE_ChannelActInact,
189: 
190: #ifdef HECCER_SOURCE_NEUROSPACES
191: 
192:             //m identification
193: 
194:             ADDRESSING_NEUROSPACES_2_HECCER(3000),
195: 
196: #endif
197: 
198: #ifdef HECCER_SOURCE_TYPING
199: 
200:             //m model source type number
201: 
202:             //! source typing is used to compute aggregate currents ao
203:             //! things.
204: 
205:             0,
206: 
207: #endif
208: 
209:         },
210: 
211:         //m first set of descriptive values, alphabetical order
212: 
213:         //m initial reversal potential
214: 
215:         0.1375262439,
216: 
217:         //m get reversal potential from this intermediary, -1 for none
218: 
219:         -1,
220: 
221:         //m maximal conductance when all channels are permissive
222: 
223:         1.394928884e-08,
224: 
225:         //m contributes to this concentration pool, -1 for none, boolean indicator only.
226: 
227:         1,
228: 
229:         //m activation description
230: 
231:         {
232:             //m power, for a standard heccer, something between 1 and 4 or so.
233: 
234:             1,
235: 
236:             //m gate definition
237: 
238:             {
239:                 //m initial value, commonly forward over backward steady states
240: 
241:                 0.038918706451336625,
242: 
243:                 //m corresponding index in tables, set to -1 for initialization.
244: 
245:                 -1,
246: 
247:                 {
248:                     //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate
249: 
250:                     {
251:                         //m multiplier
252: 
253:                         2.6e3,
254: 
255:                         //m multiplier membrane dependence, 0.0 for no dependence
256: 
257:                         0.0,
258: 
259:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
260: 
261:                         0.0,
262: 
263:                         //m choose between nominator or denominator, 1 means nominator, -1
264:                         //m means denominator
265: 
266:                         -1.0,
267: 
268:                         //m nominator or denominator offset
269: 
270:                         1.0,
271: 
272:                         //m membrane offset
273: 
274:                         0.021,
275: 
276:                         //m denormalized time constant
277: 
278:                         -8e-3,
279:                     },
280: 
281:                     //m backward kinetiks, commonly denoted with beta or perm to non-perm rate
282: 
283:                     {
284:                         //m multiplier
285: 
286:                         0.18e3,
287: 
288:                         //m multiplier membrane dependence, 0.0 for no dependence
289: 
290:                         0.0,
291: 
292:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
293: 
294:                         0.0,
295: 
296:                         //m choose between nominator or denominator, 1 means nominator, -1
297:                         //m means denominator
298: 
299:                         -1.0,
300: 
301:                         //m nominator or denominator offset
302: 
303:                         1.0,
304: 
305:                         //m membrane offset
306: 
307:                         0.04,
308: 
309:                         //m denormalized time constant
310: 
311:                         4e-3,
312:                     },
313:                 },
314:             },
315:         },
316: 
317:         //m inactivation description
318: 
319:         {
320:             //m power, for a standard heccer, something between 1 and 4 or so.
321: 
322:             1,
323: 
324:             //m gate definition
325: 
326:             {
327:                 //m initial value, commonly forward over backward steady states
328: 
329:                 0.082602128127539254,
330: 
331:                 //m corresponding index in tables, set to -1 for initialization.
332: 
333:                 -1,
334: 
335:                 {
336:                     //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate
337: 
338:                     {
339:                         //m multiplier
340: 
341:                         0.0025e3,
342: 
343:                         //m multiplier membrane dependence, 0.0 for no dependence
344: 
345:                         0.0,
346: 
347:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
348: 
349:                         0.0,
350: 
351:                         //m choose between nominator or denominator, 1 means nominator, -1
352:                         //m means denominator
353: 
354:                         -1.0,
355: 
356:                         //m nominator or denominator offset
357: 
358:                         1.0,
359: 
360:                         //m membrane offset
361: 
362:                         0.04,
363: 
364:                         //m denormalized time constant
365: 
366:                         8e-3,
367:                     },
368: 
369:                     //m backward kinetiks, commonly denoted with beta or perm to non-perm rate
370: 
371:                     {
372:                         //m multiplier
373: 
374:                         0.19e3,
375: 
376:                         //m multiplier membrane dependence, 0.0 for no dependence
377: 
378:                         0.0,
379: 
380:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
381: 
382:                         0.0,
383: 
384:                         //m choose between nominator or denominator, 1 means nominator, -1
385:                         //m means denominator
386: 
387:                         -1.0,
388: 
389:                         //m nominator or denominator offset
390: 
391:                         1.0,
392: 
393:                         //m membrane offset
394: 
395:                         0.05,
396: 
397:                         //m denormalized time constant
398: 
399:                         -10.0e-3,
400:                     },
401:                 },
402:             },
403:         },
404:     },
405: 
406:     {
407:         //m administrative overhead
408: 
409:         {
410:             //m type of structure
411: 
412:             MATH_TYPE_ChannelActInact,
413: 
414: #ifdef HECCER_SOURCE_NEUROSPACES
415: 
416:             //m identification
417: 
418:             ADDRESSING_NEUROSPACES_2_HECCER(4000),
419: 
420: #endif
421: 
422: #ifdef HECCER_SOURCE_TYPING
423: 
424:             //m model source type number
425: 
426:             //! source typing is used to compute aggregate currents ao
427:             //! things.
428: 
429:             0,
430: 
431: #endif
432: 
433:         },
434: 
435:         //m first set of descriptive values, alphabetical order
436: 
437:         //m initial reversal potential
438: 
439:         0.1470214874,
440: 
441:         //m get reversal potential from this intermediary, -1 for none
442: 
443:         -1,
444: 
445:         //m maximal conductance when all channels are permissive
446: 
447:         1.754672296e-09,
448: 
449:         //m contributes to this concentration pool, -1 for none, boolean indicator only.
450: 
451:         3,
452: 
453:         //m activation description
454: 
455:         {
456:             //m power, for a standard heccer, something between 1 and 4 or so.
457: 
458:             1,
459: 
460:             //m gate definition
461: 
462:             {
463:                 //m initial value, commonly forward over backward steady states
464: 
465:                 0.038918706451336625,
466: 
467:                 //m corresponding index in tables, set to -1 for initialization.
468: 
469:                 -1,
470: 
471:                 {
472:                     //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate
473: 
474:                     {
475:                         //m multiplier
476: 
477:                         2.6e3,
478: 
479:                         //m multiplier membrane dependence, 0.0 for no dependence
480: 
481:                         0.0,
482: 
483:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
484: 
485:                         0.0,
486: 
487:                         //m choose between nominator or denominator, 1 means nominator, -1
488:                         //m means denominator
489: 
490:                         -1.0,
491: 
492:                         //m nominator or denominator offset
493: 
494:                         1.0,
495: 
496:                         //m membrane offset
497: 
498:                         0.021,
499: 
500:                         //m denormalized time constant
501: 
502:                         -8e-3,
503:                     },
504: 
505:                     //m backward kinetiks, commonly denoted with beta or perm to non-perm rate
506: 
507:                     {
508:                         //m multiplier
509: 
510:                         0.18e3,
511: 
512:                         //m multiplier membrane dependence, 0.0 for no dependence
513: 
514:                         0.0,
515: 
516:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
517: 
518:                         0.0,
519: 
520:                         //m choose between nominator or denominator, 1 means nominator, -1
521:                         //m means denominator
522: 
523:                         -1.0,
524: 
525:                         //m nominator or denominator offset
526: 
527:                         1.0,
528: 
529:                         //m membrane offset
530: 
531:                         0.04,
532: 
533:                         //m denormalized time constant
534: 
535:                         4e-3,
536:                     },
537:                 },
538:             },
539:         },
540: 
541:         //m inactivation description
542: 
543:         {
544:             //m power, for a standard heccer, something between 1 and 4 or so.
545: 
546:             1,
547: 
548:             //m gate definition
549: 
550:             {
551:                 //m initial value, commonly forward over backward steady states
552: 
553:                 0.082602128127539254,
554: 
555:                 //m corresponding index in tables, set to -1 for initialization.
556: 
557:                 -1,
558: 
559:                 {
560:                     //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate
561: 
562:                     {
563:                         //m multiplier
564: 
565:                         0.0025e3,
566: 
567:                         //m multiplier membrane dependence, 0.0 for no dependence
568: 
569:                         0.0,
570: 
571:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
572: 
573:                         0.0,
574: 
575:                         //m choose between nominator or denominator, 1 means nominator, -1
576:                         //m means denominator
577: 
578:                         -1.0,
579: 
580:                         //m nominator or denominator offset
581: 
582:                         1.0,
583: 
584:                         //m membrane offset
585: 
586:                         0.04,
587: 
588:                         //m denormalized time constant
589: 
590:                         8e-3,
591:                     },
592: 
593:                     //m backward kinetiks, commonly denoted with beta or perm to non-perm rate
594: 
595:                     {
596:                         //m multiplier
597: 
598:                         0.19e3,
599: 
600:                         //m multiplier membrane dependence, 0.0 for no dependence
601: 
602:                         0.0,
603: 
604:                         //m 2b: multiplier membrane dependence offset, 0.0 for no dependence
605: 
606:                         0.0,
607: 
608:                         //m choose between nominator or denominator, 1 means nominator, -1
609:                         //m means denominator
610: 
611:                         -1.0,
612: 
613:                         //m nominator or denominator offset
614: 
615:                         1.0,
616: 
617:                         //m membrane offset
618: 
619:                         0.05,
620: 
621:                         //m denormalized time constant
622: 
623:                         -10.0e-3,
624:                     },
625:                 },
626:             },
627:         },
628:     },
629: };
630: 
631: 
632: struct ExponentialDecay pexdecCa[] =
633: {
634:     {
635:         //m administrative overhead
636: 
637:         {
638:             //m type of structure
639: 
640:             MATH_TYPE_ExponentialDecay,
641: 
642: #ifdef HECCER_SOURCE_NEUROSPACES
643: 
644:             //m identification
645: 
646:             ADDRESSING_NEUROSPACES_2_HECCER(5000),
647: 
648: #endif
649: 
650: #ifdef HECCER_SOURCE_TYPING
651: 
652:             //m model source type number
653: 
654:             //! source typing is used to compute aggregate currents ao
655:             //! things.
656: 
657:             1,
658: 
659: #endif
660: 
661:         },
662: 
663:         //m initial value
664: 
665:         4e-5,
666: 
667:         //m beta
668: 
669:         7.579027046e+10,
670: 
671:         //m steady state
672: 
673:         4e-05,
674: 
675:         //m tau
676: 
677:         0.00010,
678: 
679:         //m external contribution delivered by these intermediaries
680: 
681:         {
682:             0,
683:             -1,
684:             -1,
685:             -1,
686:         },
687:     },
688: 
689:     {
690:         //m administrative overhead
691: 
692:         {
693:             //m type of structure
694: 
695:             MATH_TYPE_ExponentialDecay,
696: 
697: #ifdef HECCER_SOURCE_NEUROSPACES
698: 
699:             //m identification
700: 
701:             ADDRESSING_NEUROSPACES_2_HECCER(6000),
702: 
703: #endif
704: 
705: #ifdef HECCER_SOURCE_TYPING
706: 
707:             //m model source type number
708: 
709:             //! source typing is used to compute aggregate currents ao
710:             //! things.
711: 
712:             1,
713: 
714: #endif
715: 
716:         },
717: 
718:         //m initial value
719: 
720:         4e-5,
721: 
722:         //m beta
723: 
724:         9412391936.0,
725: 
726:         //m steady state
727: 
728:         4e-05,
729: 
730:         //m tau
731: 
732:         0.00020,
733: 
734:         //m external contribution delivered by these intermediaries
735: 
736:         {
737:             2,
738:             -1,
739:             -1,
740:             -1,
741:         },
742:     }
743: };
744: 
745: 
746: int piC2m[] =
747: {
748:     2,
749:     4,
750:     -1,
751: };
752: 
753: 
754: struct MathComponentArray mca =
755: {
756:     //m number of math components
757: 
758:     4,
759: 
760:     //m math component data
761: 
762:     NULL,
763: 
764:     //m math component index, initialize to NULL
765: 
766:     NULL,
767: 
768: };
769: 
770: 
771: struct Intermediary inter =
772: {
773:     //m compartment array
774: 
775:     2,
776: 
777:     pcomp,
778: 
779:     //m all other mathematical components
780: 
781:     &mca,
782: 
783:     //m compartment 2 first mechanism number
784: 
785:     piC2m,
786: };
787: 
788: 
789: int main(int argc, char *argv[])
790: {
791:     //- determine intermediary size, and allocate
792: 
793:     struct MathComponentInfo *pmciCa = MathComponentInfoLookup(pexdecCa[0].mc.iType);
794: 
795:     struct MathComponentInfo *pmciCaT = MathComponentInfoLookup(pcaiCaT[0].mc.iType);
796: 
797:     int iChars = 2 * pmciCaT->iChars + 2 * pmciCa->iChars;
798: 
799:     void *pmc = calloc(sizeof(char), iChars);
800: 
801:     //- prepare the mechanism intermediary
802: 
803:     struct ChannelActInact *pcai0 = (struct ChannelActInact *)pmc;
804: 
805:     *pcai0 = pcaiCaT[0];
806: 
807:     struct ExponentialDecay *pexdec0 = (struct ExponentialDecay *)&((char *)pcai0)[pmciCaT->iChars];
808: 
809:     *pexdec0 = pexdecCa[0];
810: 
811:     struct ChannelActInact *pcai1 = (struct ChannelActInact *)&((char *)pexdec0)[pmciCa->iChars];
812: 
813:     *pcai1 = pcaiCaT[1];
814: 
815:     struct ExponentialDecay *pexdec1 = (struct ExponentialDecay *)&((char *)pcai1)[pmciCaT->iChars];
816: 
817:     *pexdec1 = pexdecCa[1];
818: 
819:     //- link the intermediary
820: 
821:     mca.pmc = pmc;
822: 
823:     //- do the simulation
824: 
825:     simulate(argc,argv);
826: }
827: 
828: 
829: #define main(argc,argv) simulate(argc,argv)
830: 
831: //t this prototype can give warning and perhaps errors.
832: 
833: int main(int argc, char *argv[]);
834: 
835: 
836: #include "main.c"
837: 
838: