MemFH.c

 /*	MemFH? Module					*/
 /*                                                      */
 /*	patch file for the FitzHugh?-Nagumo membrane	*/
 /*	model, Vm goes 0 to 100 mV with AP		*/
 /*                                                      */
 /*		Vrest is in mV				*/
 /*		Vt and Vp are in mV			*/
 /*		A, B, and C are in ?			*/

 /* original paper:  R FitzHugh?, "Computation of impulse initiation and */
 /*   saltatory conduction in a myelinated nerve fiber," Biophys J,     */
 /*   v.2, p.445, 1961                                                  */

 /* author of this computer code:  John B. Pormann */



 #include "CardioWave.h"

 void SetPatches?_FH( domain_t tp, vector Vm, vector Q );
 int GetF_FH( vector Vm, vector Qv, vector Fv, vector Fq, vector Av ); 

 /* FitzHugh?-Nagumo patch */
 typedef struct {
 	real w;
 } FH_patch;

 typedef struct {
 	real Iion;
 } FH_auxvar;

 /* pseudo-globals */
 int  FH_PatchSize     = sizeof(FH_patch)/sizeof(real);
 int  FH_AuxiliarySize = sizeof(FH_auxvar)/sizeof(real);
 int  FH_MemParamSize  = 0;
 byte FH_NodeType = ByteError?;

 static char* RCSID = "$Id: MemFH.c,v 1.6 2005/02/17 20:57:04 john Exp $";

 /* constants */
 static real FH_Vt =   5.0;
 static real FH_Vp = 100.0;
 static real FH_A  =   0.0;
 static real FH_B  =   0.2425;
 static real FH_C  =   1.5;
 static real FH_RestVoltage = 0.0;
 static FH_patch FH_RestPatch   = { 0.0 };

 static rword resources[] = {
 	{ "FH_A",	1001 },
 	{ "FH_B",	1002 },
 	{ "FH_C",	1003 },
 	{ "FH_Vp",	1004 },
 	{ "FH_Vt",	1005 },
 	{ "FH_IV",	1006 },
 	{ "FH_Node",	1100 },
 	{ "FH_Nodetype",1100 },
 	{ "FH_Patch",	1006 },
 	{ "FH_Type",	1100 },
 	{ "FH_Vp",	1004 },
 	{ "FH_Vr",	1007 },
 	{ "FH_Vrest",	1007 },
 	{ "FH_Vt",	1005 },
 	{ "showofs",	1200 },
 	{ "showoffset",	1200 },
 	{ "showoffsets",1200 },
 	{ "show_ofs",	1200 },
 	{ "show_offset",1200 },
 	{ "show_offsets",1200 },
 	{ NULL, 0 }
 };

 int InitMembrane?_FH( char** res ) {
 	int i,j,c;
 	int cmd;
 	real* iv;
 	real* pv;
 	logical show_ofs = false;

 	i = 0;
 	while( res[i] != NULL ) {
 		cmd = FindCommand( resources, res[i] );
 		switch( cmd ) {
 			case 1001:
 				FH_A = GetRealValue( res[i] );
 				break;
 			case 1002:
 				FH_B = GetRealValue( res[i] );
 				break;
 			case 1003:
 				FH_C = GetRealValue( res[i] );
 				break;
 			case 1004:
 				FH_Vp = GetRealValue( res[i] );
 				break;
 			case 1005:
 				FH_Vt = GetRealValue( res[i] );
 				break;
 			case 1006:
 				iv = GetRealArray( res[i] );
 				pv = (real*)(&FH_RestPatch);
 				c  = GetNumValues( res[i] );
 				if( c > FH_PatchSize ) {
 					c = FH_PatchSize;
 				}
 				for(j=0;j<c;j++) {
 					pv[j] = iv[j];
 				}
 				break;
 			case 1007:
 				FH_RestVoltage = GetRealValue( res[i] );
 				break;
 			case 1100:
 				FH_NodeType = GetByteValue( res[i] );
 				break;
 			case 1200:
 				show_ofs = GetTFValue( res[i] );
 				break;
 		}
 		i++;
 	}

 	/* required!! */
 	if( FH_NodeType == ByteError? ) {
 		return( -1 );
 	}
 	PatchSize[FH_NodeType] = FH_PatchSize;
 	if( UseAuxvars ) {
 		AuxiliarySize[FH_NodeType] = FH_AuxiliarySize;
 	} else {
 		AuxiliarySize[FH_NodeType] = 0;
 	}
 	MemParamSize[FH_NodeType]  = FH_MemParamSize;
 	FunctionTable[FH_NodeType] = GetF_FH;
 	SetpatchTable[FH_NodeType] = SetPatches?_FH;

 	if( (DebugLevel>0) and (SelfPE==0) ) {
 		printf("MemFH?: patchsize = 0.2lf %0.2lf %0.2lf %0.2lf %0.2lf\n",
 			FH_PatchSize,FH_A,FH_B,FH_C,FH_Vt,FH_Vp);
 		if( DebugLevel > 1 ) {
 			printf("MemFH?: RCSID: %s\n",RCSID);
 		}
 	}
 	if( show_ofs and (SelfPE==0) ) {
 		printf("MemFH? patch offsets:\n");
 		printf("  W: %i\n", OffsetOf?(FH_patch,w) );
 		printf("MemFH? auxvar offsets:\n");
 		printf("  Iion: %i\n", OffsetOf?(FH_auxvar,Iion) );
 	}

 	return( 0 );
 }

 void ExitMembrane?_FH( void ) {
 	return;
 }

 void SetPatches?_FH( domain_t tp, vector Vm, vector Q ) {
 	int i,j;
 	real* vm = Vm.data;
 	real* qp = Q.data;
 	real* rp = (real*)(&FH_RestPatch);
 	byte* nt = NodeType.data;

 	if( tp == Tissue ) {
 	  for(i=0;i<TissueLocalSize;i++) {
 		if( nt[i] == FH_NodeType ) {
 			vm[i] = FH_RestVoltage;
 			for(j=0;j<FH_PatchSize;j++) {
 				qp[j] = rp[j];
 			}
 		}
 		qp += PatchSize[nt[i]];
 	  }
 	}

 	return;
 }

 /* GetF() should fill in vectors Fv and Fq with the new currents/updates */
 /* NOTE: this should be from the form:  dV/dt + Fv = 0, dq/dt + Fq = 0 */
 int GetF_FH( vector Vm, vector Qv, vector Fv, vector Fq, vector Av ) {
 	int    i;
         real*  vmptr = Vm.data;
         real*  fv = Fv.data;
         real*  qm = Qv.data;
         real*  fq = Fq.data;
 	real*  av = Av.data;
         FH_patch* qp;
         FH_patch* fp;
 	FH_auxvar* ap;
         byte*  nt = NodeType.data;
 	real   vm,w,iion;

 	for(i=0;i<TissueLocalSize;i++) {
 	   if( nt[i] == FH_NodeType ) {
                 /* map pointers to patch structures */
                 qp = (FH_patch*)qm;
                 fp = (FH_patch*)fq;
 		ap = (FH_auxvar*)av;

                 /* get local variables */
                 vm = vmptr[i];
                 w  = qp->w;

 		iion = vm*(vm/FH_Vt-1.0)*(1.0-vm/FH_Vp) - w;
 		fv[i] += iion;
 		fp->w =  FH_C*( vm + FH_A - FH_B*w );

 		if( UseAuxvars ) {
 			ap->Iion = iion;
 		}
 	   } /* end-if */

 	   /* go to next patch */
 	   qm += PatchSize[ nt[i] ];
 	   fq += PatchSize[ nt[i] ];
 	   av += AuxiliarySize[ nt[i] ];
 	}

 	return( 0 );
 }
Edit - History - Print - Recent Changes - Search
Page last modified on November 23, 2009, at 10:15 AM