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: #include <stdlib.h> 20: 21: #include "../../heccer/compartment.h" 22: #include "../../heccer/heccer.h" 23: #include "../../heccer/mathcomponent.h" 24: 25: 26: #define HECCER_TEST_REPORTING_GRANULARITY 100000 27: #define HECCER_TEST_STEPS 1000000 28: #define HECCER_TEST_TESTED_THINGS ( HECCER_DUMP_VM_COMPARTMENT_MATRIX \ 29: | HECCER_DUMP_VM_COMPARTMENT_DATA \ 30: | HECCER_DUMP_VM_COMPARTMENT_OPERATIONS \ 31: | HECCER_DUMP_VM_CHANNEL_POOL_FLUXES \ 32: | HECCER_DUMP_VM_MECHANISM_DATA \ 33: | HECCER_DUMP_VM_MECHANISM_OPERATIONS \ 34: | HECCER_DUMP_VM_SUMMARY \ 35: ) 36: #define HECCER_TEST_TIME_GRANULARITY (1e-14) 37: #define HECCER_TEST_TIME_STEP (1e-11) 38: 39: 40: struct Compartment comp = 41: { 42: //m administrative overhead 43: 44: { 45: //m type of structure 46: 47: MATH_TYPE_Compartment, 48: }, 49: 50: //m index of parent compartment, -1 for none 51: 52: -1, 53: 54: /* //m first mechanism */ 55: 56: /* NULL, */ 57: 58: /* //m number of mechanisms */ 59: 60: /* 0, */ 61: 62: //m descriptive values, alphabetical order 63: 64: /* double dCm; */ 65: 66: 5.755329373e-12, // unscaled 0.0164, 67: 68: /* double dEm; */ 69: 70: -0.08, 71: 72: /* double dInitVm; */ 73: 74: -0.068, 75: 76: /* double dInject; */ 77: 78: 1e-9, 79: 80: /* double dRa; */ 81: 82: 772813.4375, // unscaled 2.5, 83: 84: /* double dRm; */ 85: 86: 8.548598272e9, // unscaled 3 87: }; 88: 89: 90: //v first calcium channel 91: 92: struct ChannelActInact caiCaT = 93: { 94: //m administrative overhead 95: 96: { 97: //m type of structure 98: 99: MATH_TYPE_ChannelActInact, 100: }, 101: 102: //m first set of descriptive values, alphabetical order 103: 104: //m initial reversal potential 105: 106: 0.1470214874, 107: 108: //m get reversal potential from this intermediary, -1 for none 109: 110: 1, 111: 112: //m maximal conductance when all channels are permissive 113: 114: 1.754672296e-09, 115: 116: //m contributes to this concentration pool, -1 for none, boolean indicator only. 117: 118: 4, 119: 120: //m activation description 121: 122: { 123: //m power, for a standard heccer, something between 1 and 4 or so. 124: 125: 1, 126: 127: //m gate definition 128: 129: { 130: //m initial value, commonly forward over backward steady states 131: 132: 0.038918706451336625, 133: 134: //m corresponding index in tables, set to -1 for initialization. 135: 136: -1, 137: 138: { 139: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 140: 141: { 142: //m multiplier 143: 144: 2.6e3, 145: 146: //m multiplier membrane dependence, 0.0 for no dependence 147: 148: 0.0, 149: 150: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 151: 152: 0.0, 153: 154: //m choose between nominator or denominator, 1 means nominator, -1 155: //m means denominator 156: 157: -1.0, 158: 159: //m nominator or denominator offset 160: 161: 1.0, 162: 163: //m membrane offset 164: 165: 0.021, 166: 167: //m denormalized time constant 168: 169: -8e-3, 170: }, 171: 172: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 173: 174: { 175: //m multiplier 176: 177: 0.18e3, 178: 179: //m multiplier membrane dependence, 0.0 for no dependence 180: 181: 0.0, 182: 183: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 184: 185: 0.0, 186: 187: //m choose between nominator or denominator, 1 means nominator, -1 188: //m means denominator 189: 190: -1.0, 191: 192: //m nominator or denominator offset 193: 194: 1.0, 195: 196: //m membrane offset 197: 198: 0.04, 199: 200: //m denormalized time constant 201: 202: 4e-3, 203: }, 204: }, 205: }, 206: }, 207: 208: //m inactivation description 209: 210: { 211: //m power, for a standard heccer, something between 1 and 4 or so. 212: 213: 1, 214: 215: //m gate definition 216: 217: { 218: //m initial value, commonly forward over backward steady states 219: 220: 0.082602128127539254, 221: 222: //m corresponding index in tables, set to -1 for initialization. 223: 224: -1, 225: 226: { 227: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 228: 229: { 230: //m multiplier 231: 232: 0.0025e3, 233: 234: //m multiplier membrane dependence, 0.0 for no dependence 235: 236: 0.0, 237: 238: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 239: 240: 0.0, 241: 242: //m choose between nominator or denominator, 1 means nominator, -1 243: //m means denominator 244: 245: -1.0, 246: 247: //m nominator or denominator offset 248: 249: 1.0, 250: 251: //m membrane offset 252: 253: 0.04, 254: 255: //m denormalized time constant 256: 257: 8e-3, 258: }, 259: 260: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 261: 262: { 263: //m multiplier 264: 265: 0.19e3, 266: 267: //m multiplier membrane dependence, 0.0 for no dependence 268: 269: 0.0, 270: 271: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 272: 273: 0.0, 274: 275: //m choose between nominator or denominator, 1 means nominator, -1 276: //m means denominator 277: 278: -1.0, 279: 280: //m nominator or denominator offset 281: 282: 1.0, 283: 284: //m membrane offset 285: 286: 0.05, 287: 288: //m denormalized time constant 289: 290: -10.0e-3, 291: }, 292: }, 293: }, 294: }, 295: }; 296: 297: 298: struct InternalNernst inCa1 = 299: { 300: //m administrative overhead 301: 302: { 303: //m type of structure 304: 305: MATH_TYPE_InternalNernst, 306: }, 307: 308: //m nernst constant 309: 310: 0.013363, 311: 312: //m link to internal concentration 313: 314: 4, 315: 316: //m constant external concentration 317: 318: 2.4000, 319: 320: //m initial nernst potential 321: 322: 0.1470214874, 323: }; 324: 325: 326: struct ChannelActInact caiCaP = 327: { 328: //m administrative overhead 329: 330: { 331: //m type of structure 332: 333: MATH_TYPE_ChannelActInact, 334: }, 335: 336: //m first set of descriptive values, alphabetical order 337: 338: //m initial reversal potential 339: 340: 0.1470214874, 341: 342: //m get reversal potential from this intermediary, -1 for none 343: 344: 3, 345: 346: //m maximal conductance when all channels are permissive 347: 348: 1.57921e-08, 349: 350: //m contributes to this concentration pool, -1 for none, boolean indicator only. 351: 352: 4, 353: 354: //m activation description 355: 356: { 357: //m power, for a standard heccer, something between 1 and 4 or so. 358: 359: 1, 360: 361: //m gate definition 362: 363: { 364: //m initial value, commonly forward over backward steady states 365: 366: 0.001391094927, 367: 368: //m corresponding index in tables, set to -1 for initialization. 369: 370: -1, 371: 372: { 373: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 374: 375: { 376: //m multiplier 377: 378: 8.50e3, 379: 380: //m multiplier membrane dependence, 0.0 for no dependence 381: 382: 0.0, 383: 384: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 385: 386: 0.0, 387: 388: //m choose between nominator or denominator, 1 means nominator, -1 389: //m means denominator 390: 391: -1.0, 392: 393: //m nominator or denominator offset 394: 395: 1.0, 396: 397: //m membrane offset 398: 399: -0.0080, 400: 401: //m denormalized time constant 402: 403: -12.5e-3, 404: }, 405: 406: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 407: 408: { 409: //m multiplier 410: 411: 35.0e3, 412: 413: //m multiplier membrane dependence, 0.0 for no dependence 414: 415: 0.0, 416: 417: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 418: 419: 0.0, 420: 421: //m choose between nominator or denominator, 1 means nominator, -1 422: //m means denominator 423: 424: -1.0, 425: 426: //m nominator or denominator offset 427: 428: 1.0, 429: 430: //m membrane offset 431: 432: 0.074, 433: 434: //m denormalized time constant 435: 436: 14.5e-3, 437: }, 438: }, 439: }, 440: }, 441: 442: //m inactivation description 443: 444: { 445: //m power, for a standard heccer, something between 1 and 4 or so. 446: 447: 1, 448: 449: //m gate definition 450: 451: { 452: //m initial value, commonly forward over backward steady states 453: 454: 0.9868968318, 455: 456: //m corresponding index in tables, set to -1 for initialization. 457: 458: -1, 459: 460: { 461: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 462: 463: { 464: //m multiplier 465: 466: 0.0015e3, 467: 468: //m multiplier membrane dependence, 0.0 for no dependence 469: 470: 0.0, 471: 472: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 473: 474: 0.0, 475: 476: //m choose between nominator or denominator, 1 means nominator, -1 477: //m means denominator 478: 479: -1.0, 480: 481: //m nominator or denominator offset 482: 483: 1.0, 484: 485: //m membrane offset 486: 487: 0.029, 488: 489: //m denormalized time constant 490: 491: 8.0e-3, 492: }, 493: 494: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 495: 496: { 497: //m multiplier 498: 499: 0.0055e3, 500: 501: //m multiplier membrane dependence, 0.0 for no dependence 502: 503: 0.0, 504: 505: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 506: 507: 0.0, 508: 509: //m choose between nominator or denominator, 1 means nominator, -1 510: //m means denominator 511: 512: -1.0, 513: 514: //m nominator or denominator offset 515: 516: 1.0, 517: 518: //m membrane offset 519: 520: 0.023, 521: 522: //m denormalized time constant 523: 524: -8.0e-3, 525: }, 526: }, 527: }, 528: }, 529: }; 530: 531: 532: struct InternalNernst inCa2 = 533: { 534: //m administrative overhead 535: 536: { 537: //m type of structure 538: 539: MATH_TYPE_InternalNernst, 540: }, 541: 542: //m nernst constant 543: 544: 0.013363, 545: 546: //m link to internal concentration 547: 548: 4, 549: 550: //m constant external concentration 551: 552: 2.4000, 553: 554: //m initial nernst potential 555: 556: 0.1470214874, 557: }; 558: 559: 560: struct ExponentialDecay exdecCa = 561: { 562: //m administrative overhead 563: 564: { 565: //m type of structure 566: 567: MATH_TYPE_ExponentialDecay, 568: }, 569: 570: //m initial value 571: 572: 4e-5, 573: 574: //m beta 575: 576: 7.579027046e+10, 577: 578: //m steady state 579: 580: 4e-05, 581: 582: //m tau 583: 584: 0.00010, 585: 586: //m external contribution delivered by these intermediaries 587: 588: { 589: 0, 590: 2, 591: -1, 592: -1, 593: }, 594: }; 595: 596: 597: int piC2m[] = 598: { 599: 5, 600: -1, 601: }; 602: 603: 604: struct MathComponentArray mca = 605: { 606: //m number of math components 607: 608: 5, 609: 610: //m math component data 611: 612: NULL, 613: 614: //m math component index, initialize to NULL 615: 616: NULL, 617: 618: }; 619: 620: 621: struct Intermediary inter = 622: { 623: //m compartment array 624: 625: 1, 626: 627: &comp, 628: 629: //m all other mathematical components 630: 631: &mca, 632: 633: //m compartment 2 first mechanism number 634: 635: piC2m, 636: }; 637: 638: 639: int main(int argc, char *argv[]) 640: { 641: //- determine intermediary size, and allocate 642: 643: struct MathComponentInfo *pmciCaT = MathComponentInfoLookup(caiCaT.mc.iType); 644: 645: struct MathComponentInfo *pmciCaP = MathComponentInfoLookup(caiCaP.mc.iType); 646: 647: struct MathComponentInfo *pmciCa = MathComponentInfoLookup(exdecCa.mc.iType); 648: 649: struct MathComponentInfo *pmciNernst1 = MathComponentInfoLookup(inCa1.mc.iType); 650: 651: struct MathComponentInfo *pmciNernst2 = MathComponentInfoLookup(inCa2.mc.iType); 652: 653: int iChars = pmciCaT->iChars + pmciCaP->iChars + pmciCa->iChars + pmciNernst1->iChars + pmciNernst2->iChars; 654: 655: void *pmc = calloc(sizeof(char), iChars); 656: 657: //- prepare the mechanism intermediary 658: 659: struct ChannelActInact *pcaiCaT = (struct ChannelActInact *)pmc; 660: 661: *pcaiCaT = caiCaT; 662: 663: struct InternalNernst *pin1 = (struct InternalNernst *)&((char *)pcaiCaT)[pmciCaT->iChars]; 664: 665: *pin1 = inCa1; 666: 667: struct ChannelActInact *pcaiCaP = (struct ChannelActInact *)&((char *)pin1)[pmciNernst1->iChars]; 668: 669: *pcaiCaP = caiCaP; 670: 671: struct InternalNernst *pin2 = (struct InternalNernst *)&((char *)pcaiCaP)[pmciCaP->iChars]; 672: 673: *pin2 = inCa2; 674: 675: struct ExponentialDecay *pexdec = (struct ExponentialDecay *)&((char *)pin2)[pmciNernst2->iChars]; 676: 677: *pexdec = exdecCa; 678: 679: //- link the intermediary 680: 681: mca.pmc = pmc; 682: 683: //- do the simulation 684: 685: simulate(argc,argv); 686: } 687: 688: 689: #define main(argc,argv) simulate(argc,argv) 690: 691: //t this prototype can give warning and perhaps errors. 692: 693: int main(int argc, char *argv[]); 694: 695: 696: #include "main.c" 697: 698: 699: