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