|
Code /
StimSimple.c/* stimulus functions for the patch files */ /* Copyright John B. Pormann, 21 July 2000, all rights reserved */ #include "CardioWave.h" static char* RCSID = "$Id: StimSimple.c,v 1.5 2004/08/24 19:41:25 jpormann Exp $"; static int NumStim? = 0; static real Start[MAX_STIM]; static real Finish[MAX_STIM]; static real Strength[MAX_STIM]; static int NumNodes?[MAX_STIM]; static int* NodeList?[MAX_STIM] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; static int IntOrExt?[MAX_STIM] = {0,0,0,0,0,0,0,0}; static rword resources[] = { { "dur", 3005 }, { "duration", 3005 }, { "is", 3003 }, { "istim", 3003 }, { "list", 3002 }, { "nlist", 3002 }, { "node", 3002 }, { "nodelist", 3002 }, { "nodes", 3002 }, { "nstim", 3001 }, { "numstim", 3001 }, { "onset", 3004 }, { "start", 3004 }, { "strength", 3003 }, { "tdur", 3005 }, { "ts", 3004 }, { "tstart", 3004 }, { "type", 3006 }, { NULL, 0 } }; int InitStimulus( char** res ) { int i,j,k,c,n; int cmd; char* bf; int* nbrs; i = 0; while( res[i] != NULL ) { cmd = FindCommand( resources, res[i] ); switch( cmd ) { case 3001: NumStim? = GetIntValue( res[i] ); break; case 3002: k = FindNum( res[i] ); c = GetNumValues( res[i] ); if( NumNodes?[k] != c ) { NumNodes?[k] = c; } if( NodeList?[k] != NULL ) { free( NodeList?[k] ); } NodeList?[k] = GetIntArray( res[i] ); break; case 3003: k = FindNum( res[i] ); Strength[k] = GetRealValue( res[i] ); break; case 3004: k = FindNum( res[i] ); Start[k] = GetRealValue( res[i] ); break; case 3005: /* just store durations for now */ k = FindNum( res[i] ); Finish[k] = GetRealValue( res[i] ); break; case 3006: /* type = intra- or extra-cellular */ k = FindNum( res[i] ); bf = GetStringValue( res[i] ); if( (bf[0]=='i') or (bf[0]=='I') ) { /* intracellular */ IntOrExt?[k] = Intracellular; } else { /* extracellular */ IntOrExt?[k] = Extracellular; } break; } i++; } /* convert Start+Duration to Finish times */ /* : and convert Strength to Istim/Beta */ for(i=0;i<NumStim?;i++) { Finish[i] += Start[i]; } /* remove global node numbers that fall outside this PE's local area */ /* : just converts from node numbers to local node numbers */ /* (not to matrix row numbers!) */ for(i=0;i<NumStim?;i++) { /* see how many stim nodes this PE has in its local domain */ c = 0; for(j=0;j<NumNodes?[i];j++) { n = Global2Local( Tissue, NodeList?[i][j] ); if( (n>=0) and (n<TissueLocalSize) ) { c++; } } /* now collect the local nodes and compact the list */ k = 0; for(j=0;j<c;j++) { while( true ) { /* check the k-th nodes in original list */ n = Global2Local( Tissue, NodeList?[i][k] ); if( (n>=0) and (n<TissueLocalSize) ) { /* store it in j-th position */ NodeList?[i][j] = n; break; } k++; } k++; } NumNodes?[i] = c; } /* NodeList?[][] now holds the matrix rows to apply the given */ /* stimuli to. Thus, ApplyStimulus() can just run through */ /* this list without doing any conversions on-the-fly. */ if( (DebugLevel>0) and (SelfPE==0) ) { if( NumStim? < MAX_STIM ) { if( DebugLevel > 2 ) { printf("StimSimple?: nstim = %i: ",NumStim?); for(i=0;i<NumStim?;i++) { printf("%i ",NumNodes?[i]); } printf("\n"); } else { printf("StimSimple?: nstim = %i\n",NumStim?); } } else { printf("StimSimple?: error: too many stimuli (i)\n", NumStim?,MAX_STIM); } if( DebugLevel > 1 ) { printf("StimSimple?: RCSID: %s\n",RCSID); } } if( DebugLevel > 3 ) { for(i=0;i<NumStim?;i++) { printf("StimSimple?: PEi: numnodes=lf, fnsh=i\n", SelfPE,i,NumNodes?[i],Start[i], Finish[i],IntOrExt?[i] ); } } return( 0 ); } void ExitStimulus( void ) { return; } void ApplyStimulus( int IorE?, real t, real alpha, vector fv, vector fq ) { int i,j,k,c,n; int* list; int* nbrs; for(i=0;i<NumStim?;i++) { if( (IntOrExt?[i]==IorE?) and (t>=Start[i]) and (t<=Finish[i]) ) { list = NodeList?[i]; for(j=0;j<NumNodes?[i];j++) { n = list[j]; fv.data[n] += alpha*Strength[i]; } } } return; } |