The Grid unit has the largest API of all units, since it is the custodian of the bulk of the simulation data, and is responsible for most of the code housekeeping. The Grid_init routine, like all other Unit_init routines, collects the runtime parameters needed by the unit and stores values in the data module. If using UG, the Grid_init also creates the computational domain and the housekeeping data structures and initializes them. If using AMR, the computational domain is created by the Grid_initDomain routine, which also makes a call to mesh package's own initialization routine. The physical variables are all owned by the Grid unit, and it initializes them by calling the Simulation_initBlock routine which applies the specified initial conditions to the domain. If using an adaptive grid, the initialization routine also goes through a few refinement iterations to bring the grid to desired initial resolution, and then applies the Eos function to bring all simulation variables to thermodynamic equilibrium. Even though the mesh-based variables are under Grid's control, all the physics units can operate on and modify them.
A suite of get/put accessor/mutator functions allows the calling unit to fetch or send data by the block. One option is to get a pointer Grid_getBlkPtr, which gives unrestricted access to the whole block and the client unit can modify the data as needed. The more conservative but slower option is to get some portion of the block data, make a local copy, operate on and modify the local copy and then send the data back through the “put” functions. The Grid interface allows the client units to fetch the whole block (Grid_getBlkData), a partial or full plane from a block (Grid_getPlaneData), a partial or full row (Grid_getRowData), or a single point (Grid_getPointData). Corresponding “put” functions allow the data to be sent back to the Grid unit after the calling routine has operated on it. Various getData functions can also be used to fetch some derived quantities such as the cell volume or face area of individual cells or groups of cells. There are several other accessor functions available to query the housekeeping information from the grid. For example Grid_getListOfBlocks returns a list of blocks that meet the specified criterion such as being “LEAF” blocks in PARAMESH, or residing on the physical boundary.
In addition to the functions to access the data, the Grid unit also provides a collection of routines that drive some housekeeping functions of the grid without explicitly fetching any data. A good example of such routines is Grid_fillGuardCells. Here no data transaction takes place between Grid and the calling unit. The calling unit simply instructs the Grid unit that it is ready for the guard cells to be updated, and doesn't concern itself with the details. The Grid_fillGuardCells routine makes sure that all the blocks get the right data in their guardcells from their neighbors, whether they are at the same, lower or higher resolution, and if instructed by the calling routine, also ensures that EOS is applied to them.
In large-scale, highly parallel FLASH simulations with AMR, the processing of Grid_fillGuardCells calls may take up a significant part of available resource like CPU time, communication bandwidth, and buffer space. It can therefore be important to optimize these calls in particular. From FLASH3.1, Grid_fillGuardCells provides ways to
Another routine that may change the global state of the grid is Grid_updateRefinement. This function is called when the client unit wishes to update the grid's resolution. again, the calling unit does not need to know any of the details of the refinement process.