|
Dev /
MembraneModuleThe membrane module is perhaps the easiest module to write. It involves, in it's simplest form, only 4 functions: InitMembrane?(), ExitMembrane?(), SetPatches?()and GetF?(). As an example, look at the FitzHugh?-Nagumo membrane model: ![]() In the C code for the GetF?(), we find a loop over a global variable called LocalSize?. LocalSize? indicates how many nodes in the global domain this particular processor is working with. In parallel situations, not every processor will have the exact same number of nodes (ie. 1001 nodes split on 10 processors leaves some PEs? with 100 nodes to work on, and one PE has 101 nodes in its subdomain). In sequential (single PE) situations, LocalSize? will equal SystemSize? (another global variable). We then go through each node in turn, using the input vectors, Vm and Q, to compute the "ionic" or transmembrane current. NOTE that the transmembrane current is ADDED to the vector Fv while the state variable portions, Fq(), OVERWRITE the vector Fq. The function SetPatches?() is usually (but not always) called during the initialization phase. In the event that we are reading an initial value from a file on disk (perhaps from a restart situation), then this function will not be called. This is somewhat important to note since it should not be relied upon to do any initialization. The SetPatches?() function simply sets all of the voltages and state variables to some predefined state. Usually this is the resting state, but in models with no well-defined rest state, it is simply a predefined value. There should be a useable default value encoded into the module (ie. don't just assign everything to zero unless that is physiologically meaningful) and the user should be able to alter this predefined state (thus the membrane programmer should look for the "RestVoltage?" and "RestPatch?" resource settings). In some cases, the vfill() function can be used to fill in the vector with a constant value. In other cases, it may be easier to create a "patch" structure, and then copy from that patch structure into an aliased form of the vector. This is done in the example code. At the very top of the program, we define "typedef struct{ ... } patch" which both defines the structure and renames it a patch. Then, the first thing we do inside of SetPatches?() is to create a patch pointer and point it inside the Q vector's data area. Thus, patch p[0] points to the first patch's data inside the Q vector, patch p[1] points to the next patch's data, etc. The loop to initialize Q is then very simple, we set each patch equal to the rest patch (defined earlier, and perhaps changed by the user). Since we've previously defined what a patch structure is, the C compiler understands that "patch 1 equals patch 2" means to copy so many bytes of data from area 2 to area 1. |