Templated Modules
Our CoulombsLaw
module hard-coded the floating type to double
. In
practice we can get a factor of 2 speed-up by using float
instead of
double
. The trade-off is that float
has reduced precision and is thus
not applicable in all situations. Nonetheless, if we want to support both
float
and double
the easiest way to do this is by templating our module
on the floating-point type. To this end, this section looks at how to write a
module TemplatedCoulombsLaw
, which is templated on the floating-point type.
Note
In practice, rather than declaring a whole new module
TemplatedCoulombsLaw
you would probably just modify the CoulombsLaw
module; however, in order to maintain two separate tutorials we opted to
create a new module.
Templating slightly changes how the module is declared:
#pragma once
#include <pluginplay/pluginplay.hpp>
namespace pluginplay_examples {
template<typename FloatingPointType>
DECLARE_MODULE(TemplatedCoulombsLaw);
} // namespace pluginplay_examples
specifically we need to include a template<typename FloatingPointType>
statement before the call to MODULE_RUN
(template<class FloatingPointType>
would work too). The more significant
changes are to the definition of the module where we have to use different
macros: TEMPLATED_MODULE_CTOR
and TEMPLATED_MODULE_RUN
. In addition to
taking the name of the module, these macros also take a list of all template
parameters.
#include "electric_field.hpp"
#include "modules.hpp"
#include <numeric> // For std::inner_product
static constexpr auto module_desc = R"(
template<typename FloatingPointType>
TEMPLATED_MODULE_CTOR(TemplatedCoulombsLaw, FloatingPointType) {
description(module_desc);
satisfies_property_type<prop_type>();
}
template<typename FloatingPointType>
TEMPLATED_MODULE_RUN(TemplatedCoulombsLaw, FloatingPointType) {
const auto& [r, charges] = prop_type::unwrap_inputs(inputs);
// This will be the value of the electric field
Point E{0.0, 0.0, 0.0};
auto rv = results();
return prop_type::wrap_results(rv, E);
}