Skip to content

Simulation Design

Stephen Berry edited this page May 24, 2016 · 6 revisions

Note: When speaking of modules and handling modules, the following commentary assumes that the handling is performed via Link container classes unless otherwise stated.

Variables

At the core of clean, understandable, simulation code is separating variables into small, critically associated groups. Classes with large numbers of variables or with widely unrelated variables is a sign of poor design. Variable names should also be easily understandable or follow well known scientific conventions.

Tracking

Use ascVar(x) (sets variable x to have associated string: "x")
Important: Only call ascVar(x) on variables within the module that instantiates them. This is because the internal tracker stores a pointer to the variable, which will become invalid if the module owning the variable is deleted.

Adding Modules During Simulation

When adding modules during a simulation it is usually an error to add them during the middle of an update() call. This is because update() is often called multiple times in a given step.

Modules As Simulators

Every module can perform as a simulator, allowing straightforward testing of single modules while allowing them to be implemented in larger systems and across projects without changing any code.

Protecting Module Manipulation

If another module needs to access a module's variables, but shouldn't manipulate the other module's variables, then the Link container should const qualify the module.

class System : public asc::Module
{
public:
   asc::Link<const Spring> spring;
   . . .
}

In this example the System will be able to access the spring's variables, but it won't be able to manipulate any of them. The Ascent library is designed so that under the hood (even if this provides the only instance of Spring) the spring object will be updated and changed, but its access within System will be const qualified.

Multi-Threading

In order to allow Ascent modules to be run in either single or multi-threaded simulations, a size_t sim must be the first element added to every module's constructor.
Note: A module instance only belongs to one simulator, but may be accessible to modules in other simulators: multi-threaded simulations can be interconnected.