MNRSIM README MODULES ===================== LabWindows is a C based compiler, and while C is NOT an object oriented language, C can still be used to provide a structured environment. This structure is not enforced by the compiler, it is up to individual programmers to maintain structure. At this writing, MNRSIM is over 12,000 lines of C code, or roughly 200+ pages. No single programmer can hope to sit down and read all of this code and understand every detail in a short period of time. A module in MNRSIM is a C file which collects together a related group of functions. Related modules are also often lumped together and communicate extensively with other modules that perform similar functions. A top level breakdown looks like this: 1. LabWindows GUI 2. User Supplied Call Back Functions 3. Variable Store 4. Physics Modules 5. Supplementary Modules The LabWindows GUI communications with the Microsoft Operating system (Windows 98,2000,XP ect) and interprets mouse clicks and keyboard strokes as well as determining what windows to draw. The Call Back Functions communicate with the GUI, the variable store and the various physics modules. The physics modules implement the basic physical routines of the system. Currently this includes the flux calculation, the cell cross section calculation, the Hardy Cross pressure and flow calculations the thermal transport calculation and the thermal transfer calculation. The supplementary modules handle issues related to simulation management like the time-line, or the loading and saving of simulation snapshots. Generally all functions within a file have a name which uses the file name as its prefix. So for example cell_foo(), is a function in the cell.c file. User Supplied Call Back Functions --------------------------------- The LabWindows user interface editor lets the programmer define call back functions for the various widgets. When the program is running and someone clicks on a button LabWindows executes the code that has been listed as a call back. This gives the programmer a way to define responses to the LabWindows buttons and slider. In MNRSIM call back functions are grouped together by which panel they refer to, and in every case they use "_cbf_" as part of their name. So for example cell_cbf.c Defines several call back functions for the file cell.uir All of the functions in cell_cbf.c use the prefix "cell_cbf_" as part of their name. So for example the button foo in the cell panel has a call back function named "cell_cbf_foo". Maintaining a consistent name convention like this makes it very easy to see how things are connected. If the function had some random name like "foobar()" when you saw that function in a source file you would have no idea that it was a call back function, and when you saw that function in the LabWindows .uir editor you would have no idea what file it was in. Process graphs are special submenus that are drawn in a graph like way, with lines connecting buttons. The call backs for these buttons are often stored in separate files. All the call back files are listed below: cdis_cbf.c Core Display call backs cell_cbf.c Cell panel call backs ctrl_cbf.c Control panel call backs ctrlgr_cbf.c Control panel process graph call backs flux_cbf.c Flux panel call backs fluxgr_cbf.c Flux panel process graph call backs htgr_cbf.c Heat Transport/Transfer process graph call backs httf_cbf.c Heat Transfer call back functions sche_cbf.c Schematic call backs Variable Store -------------- MNRSIM uses a special module called "share.c" to represent global variables. Use of the module share is discussed both in the comments for share.c, as well as in the general readme file. Global variables present several difficult programming risks, for example. Suppose that int C; is defined as a global variable in one of the source files and is accessible from all the other modules. Now suppose that one module implements a loop in a function like this: /*---module_A---*/ ... void foo() { ... for(C=1; C<100; C++) { ... } ... /*---end_module_A---*/ Now suppose that a second module has a similar function which calls the first module as: /*---module_B---*/ ... void bar() { for(C=1; C<200; C++) foo() } /*---end_module_B---*/ In this case since the variable C is shared between module A and module B. The loop in module B's function bar() will never terminate because module A keeps changing this variable for every iteration of the loop in module_B. This kind of error becomes more and more likely as a program increases in size, so, shared variables are used to avert this. Variables kept in the shared store are normally key to the simulation and also likely to be accessed by a variety of modules. All of the shared variable structures are listed in share.h, some of the important ones are: SCEL Cell library SCEL_DESCR Description of the cell library, size ect. SGRD Grid which stores flux & Rod temperatures SGRD_DESCR Grid description, dimension, group #s ect. SPIPES Pipe network SPIPE_DESCR Description of pipe network, includes pool temps ect. The other important set of global variables which are not defined as part of the shared variable system are the panel handles. Panel handles should only be defined once in the main module, and can be considered as read-only variables and so are technically safe in terms of the kind of global variable snafu described above. Panel handles use a simple naming convention, the word "panel_" plus a suffix which corresponds to the Panel handle that they are representing. So for example: panel_cell Cell input panel panel_core Core definition panel panel_hts1 heat transport system 1 panel_time time line See the main.c file for a complete listing. Physics Modules --------------- MNRSIM is primarily meant to be a reactor simulator so a large proportion of the modules are devoted to modeling physics. The physics modules are listed below: CELL.C cross section handling, derived from Dr. Garlands original CELL.C program FLUX.C computes flux densities using the neutron diffusion equation flux_memio.c Memory an I/O handling related to FLUX.C, not actually a physics module rather a helper ht_transf.c Heat Transfer from core to fluid ht_transp.c Heat Transport through the pipe network hyd.c hydraulics calculation using Hardy Cross vop.c Virtual Operator Dr. Garland wrote specifications for the Heat Transfer, Heat Transport and hardy cross modules. These documents are the best references for defining in physical terms precisely what the modules do. The physics modules solve various linear and non linear problems based on the input derived from the user interface. They compute their solutions and save the results in variables that are kept in the shared store. Supplementary Modules --------------------- Several modules are neither physics modules, nor call back functions, but rather encode a variety of service routines for maintaining the system. These include: glgraph.c Plots the 3d flux image using open gl primitives main.c location of the "main()" function as well as other initialization and data management routines share.c Shared variable store, already discussed time.c management of things time oriented Adding a module =============== In order to add a module to MNRSIM you must: a) create a file suffixed by ".c" b) edit the project and add the new file to the project c) include both the files "common.h" and "share.h" common.h keeps a list of all the commonly exported functions. It is important to NOT export each and every function in a module but rather only the ones that will be used externally. The common.h file thus represents the external interface of all the modules. This is a good function to look at to get another picture of the general overview of MNRSIM. d) name your functions starting with the module name. There will often be a "main" function for your module. Included as part of MNRSIM is a simple module called "test.c" which shows how shared variables are accessed, and which files are included. e) Define an activation method for the module. Modules can be activated in a variety of ways. i) Their functions can be called from other modules ii) They can be initiated by a LabWindows mouse click, by making them part of a call back function iii) They can be inserted into the time_sim() function. time_sim() is the function which is called when either a virtual operator is started, or when the SIM button is clicked on. time_sim() is the main loop which executes each of the physics modules for one time slice. time_sim() estimates a value for dt based on the responses from each of the physics modules that it calls, and it will choose the smallest dt as the effective dt. A module called by time_sim() is expected to model a period of time equal to dt. It should return promptly, and it should never cause the program to exit or hang for a long period of time. Physics modules are expected to share CPU time, and are expected to be gracious about it. Ideally each module would execute for about the same amount of real time. Practically it is understood that some parts of the simulation are more computationally demanding than others. Some parts of the simulation that are not time dependent must be called before the time dependent part of the simulation is initiated. To understand how these modules work (flux_main() is an example) look at the call back function for the SIM button which is stored in the sche_cbf.c file as sche_cbf_run(). This function makes several decisions about exactly how the simulation will run, and whether the flux module will be run or not.