ODT
Loading...
Searching...
No Matches
General Code Structure

Once downloaded, open the ODT folder. You will see the following set of directories:

  • build/Build files
  • source/ — ODT source code
  • input/ — Input files
  • run/ — ODT executables and runtime files
  • data/ — Data produced by the ODT code
  • post/ — Data post-processing tools
  • docs/ — Code documentation

The ODT code is structured with a collection of C++ classes.

  • Nearly all variables are public. This avoids excessive get and set functions and allows easy access to class members. (We are responsible adults here...)
  • The domain.cc is the main class. It contains all the domain variables (cell positions, velocities, and all scalar profiles). It holds the Cantera objects, solver, eddy, mesh manager, odt case and other basic class objects.
    • This class a vector of pointers called v to dv objects (domain variables). This is convenient for treating the collection. There are also explicit pointers to specific domain variable objects, so that these can be conveniently referenced by name. Because they are pointers, they may not all be instantiated though.
    • Basic domain operations are included in this class, like domainPositionToIndex.
    • There are generally two instantiations of domains, the main domain domn, and an eddy domain eddl, which holds fewer variables. The eddy domain object is only used for eddy events.
    • Nearly every class in the code has a back pointer to the domain object so that every class has access to every other class.
  • The domain objects domn and eddl are instantiated in main.cc, as are many other key classes, such as the solver, mesh manager, cantera objects, random generator.
  • All domain profile variables (such as grid positions, velocities, temperatures, densities, etc.) are somain variable classes dv_uvw that inherit from a parent: dv.
    • The dv class holds the variable name, a vector of its data values on the domain, flags for whether it is transported or output in a data file, and vectors holding its source and transport terms in the case it is a transported quantity.
    • It also performs functions for setting itself, as well as merging and splitting cells, and setting its source and transport quantities.
      • These functions serve as defaults, and are only specialized by children as needed.
    • The child classes specialize functions and define variables that are only needed by themselves. For example, the dv_ygas class has nspc that holds the number of gas species (effectively the number of dv_ygas), along with a kMe index so that each dv_ygas object knows its place. This is useful for allowing the first dv_ygas object to set properties for all the others to avoid redundancy. For example, normally all reaction rates for species are computed at once, but that needs special treatment when each species is its own domain variable and computes its own source term.
  • The solver class organizes the eddy sampling and diffusive advancement progression.
    • The eddy class contains functions for performing triplet maps, eddy time scales, sampling eddy locations and sizes, and applying velocity kernels.
    • The micromixer class contains functions for performing the diffusive advancement. This includes the time (for temporal flows) or space (for spatial flows) integration of the governing PDEs, which is done using the method of domains with a finite volume scheme on an adaptive mesh. The micromixer calls the rate functions for all domain variable source and transport terms and performs explicit or semi-implicit time (or space) integration.
    • the meshManager class performs mesh adaption, as described in the theory paper below.
  • Other supporting classes include the streams class for defining mixing streams, and performing mixture fraction calculations, the radiation class, which contributes to the enthalpy source term for combustion simulations, the randomGenerator class, the processor class for handling parallel MPI details, and the inputoutput class for I/O.
  • The odtparam class holds most of the ODT parameters that are read from input files and used throughout the code.
  • ODT case files were mentioned previously. These are in the domaincases/ directory, for example domaincase_channel. They inherit from a parent domaincase.
    • These cases are used to specify the domain variables needed for a given case. Some are fairly common: pos, posf, rho, dvisc, uvel, vvel, wvel, while others are more specific, such as chi, mixf, temp, hr.
    • The parent class holds only a pointer to the domn object, but defines functions like those that set the gas state, or set case specific variables, that are useful for the children. These make it very easy to have generic code that can support multiple cases with multiple domain variables. The defaults allow certain children, such as domaincase_channel to be fairly small. Other classes can specialize as needed.
    • The domaincase_* classes also are responsible for initializing the domain variable profiles prior to running. Each domain variable has its own defaults, but the specific case allows for, e.g., initializing a jet velocity profile. This can be done by adding parameters to the input.yaml file and reading those values in the given odt case file. As needed, supporting setup files could be used.