walker::DiffEqStack class

Differential equations stack.

Constructors, destructors, conversion operators

DiffEqStack() explicit
Constructor: register differential equations into factory.

Public functions

auto selected() const -> std::vector<DiffEq>
Instantiate selected DiffEqs.
auto tables() const -> std::pair<std::vector<std::string>, std::vector<tk::Table<1>>>
Instantiate tables from which extra statistics data to be output sampled for all selected differential equations.
auto factory() const -> const DiffEqFactory&
Constant accessor to differential equation factory.
auto info() const -> std::vector<std::vector<std::pair<std::string, std::string>>>
Return info on selected differential equations.
auto ntypes() const -> std::size_t
Return number of unique equation types registered.

Function documentation

walker::DiffEqStack::DiffEqStack() explicit

Constructor: register differential equations into factory.

This constructor consists of several blocks, each registering a potentially large number of entries in the differential equation factory, m_factory, which is of type walker::DiffEqFactory, a std::map. At this time, each type of differential equation can be configured to use a unique initialization policy and a unique coefficients policy. (More types of policies will most likely come in the future.) The policy classes are template arguments to the differential equation classes and influence their behavior in a different way, abstracting away certain functions, e.g., how to set initial conditions and how to update their coefficients during time integration. For more information on policy-based design, see http://en.wikipedia.org/wiki/Policy-based_design. This abstraction allows separation of concerns.

Since the functionality of the policies are orthogonal to each other, i.e., they do not depend on each other or their host (the differential equation class), a Cartesian product of combinations are possible, depending on which policies are selected. This constructor registers all possible combinations of policies for all available differential equations. By register, we mean, an entry is recorded in an associative container, a std::map, that associates a lightweight key of type walker::ctr::DiffEqKey, consisting of only an enum for each policy type, to an std::function object that holds the constructor bound to its arguments corresponding to a particular differential equation + policies combination. Note that registering these entries in the map does not invoke the constructors. The mapped value simply stores how the constructors should be invoked at a later time. At some point later, based on user input, we then instantiate only the differential equations (and only those configurations) that are requested by the user.

Since all differential equation types (registered in the factory) "inherit" from a common "base", client-code is unform and generic, and thus immune to changes in the inner workings of the particular differential equations as long as they fullfill certain concepts, i.e., implement certain member functinos, enforced by the common base, DiffEq. The words "inherit and "base" are quoted here, because the common base does not use inheritance in the normal OOP sense and does not use reference semantics, i.e., pointers, visible to client-code either. The relationship is more of a models a-type, which simplifies client-code and allows for the benfits of runtime inheritance with value-semantics which is less error prone and easier to read. See more about the models-a relationship and its implementation in DiffEq/DiffEq.h.

The design discussed above allows the registration, instantiation, and use of the differential equations to be generic, which eliminates a lot of boiler-plate code and makes client-code uniform.

Details of registration using brigand::for_each and tk::cartesian_product:

The template argument to brigand::for_each, as used below, requires a list of list of types. We use brigand::list of brigand::list of types, listing all possible policies, where the inner list must have exactly two types, as the list of lists is constructed from two lists using the cartesian product, and the length of the outer list (the list of lists) is arbitrary. The constructor argument to brigand::for_each is a functor that is to be applied to all members of the outer list. tk::cartesian_product will create all possible combinations of these types and call the functor with each type of the created sequence as a template parameter. The functor here inherits from registerDiffEq, which, i.e., its constructor call, needs a single template argument, a class templated on policy classes. This is the differential equation class to be configured by selecting policies and to be registered. The arguments to registerDiffEq's constructor are the factory, the enum denoting the differential equation type, and a reference to a variable of type std::set< ctr::DiffEqType >, which is only used internally to DiffEqStack for counting up the number of unique differential equation types registered, used for diagnostics purposes.

std::vector<DiffEq> walker::DiffEqStack::selected() const

Instantiate selected DiffEqs.

Returns std::vector of instantiated differential equation objects

std::pair<std::vector<std::string>, std::vector<tk::Table<1>>> walker::DiffEqStack::tables() const

Instantiate tables from which extra statistics data to be output sampled for all selected differential equations.

Returns Vector of names and tables to sample from during time stepping

const DiffEqFactory& walker::DiffEqStack::factory() const

Constant accessor to differential equation factory.

Returns Constant reference to the internal differential equation factory

std::vector<std::vector<std::pair<std::string, std::string>>> walker::DiffEqStack::info() const

Return info on selected differential equations.

Returns A vector of vector of pair of strings, containing the configuration for each selected differential equation

std::size_t walker::DiffEqStack::ntypes() const

Return number of unique equation types registered.

Returns The number of unique equation types registered in the factory