Designing a Module

The previous pages covered how to actually code up a module. They did not provide any guidance on how to design your module.

Additional Inputs

The property type APIs are necessarily general and rigid. This can pose difficulties when your module needs additional input. PluginPlay provides you with two options for obtaining the extra input your module needs:

  1. Define a module-specific input parameter

  2. Call a submodule

Module-Specific Input

Many algorithms have algorithmic parameters associated with them such as thresholds, tolerances, maximum number of iterations, etc.. Generally speaking it is best to expose these parameters to the user and not hardcode them. These parameters are typically not exposed through the property type and thus can not be set by the caller as positional arguments. At the same time it is usually the end-user, not the calling function, which wants to manipulate these parameters, e.g. it is the end-user which has decided that a particularly tight energy convergence criteria is needed not the function which is requesting the energy. For these types of parameters it makes sense to make them module-specific inputs.

In our ScreenedCoulombsLaw example (TODO: Add link) we used a threshold to determine when point charges should be screened out. This threshold is really an algorithmic detail. Once it has been set (either to the default value or by the end-user) it generally won’t be touched again. The other option, having this threshold be set by a submodule doesn’t really make a whole lot of sense because there really isn’t an algorithm that can compute it (typically the default value is determined by extensive benchmarking which establishes what value produces a tolerable error; while that process could be encapsulated in a module, once it’s been done you might as well just use the value).

Call a Submodule

Module-specific inputs are primarily for algorithmic parameters. Submodules are used primarily to establish data dependencies among computed properties. For example in our ClassicalForce tutorial (TODO: add link) we used a submodule to establish that when we compute the force on the particle it will depend on the electric field (which in general must also be computed). We did this by calling a submodule that satisfied the ElectricField property type. By using a submodule instead of a hard-coded call our ClassicalForce module works with both the CoulombsLaw and ScreenedCoulombsLaw submodules (as well as any other modules users choose to write which satisfy the ElectricField property type).

Using a module-specific input, for the electric field, in the ClassicalForce module doesn’t make a lot of sense because: the value of the electric field is system dependent (needs to be computed for every system) and the end-user typically doesn’t have the value sitting around (unless they’ve already called a module satisfying the ElectricField property type).