Skip to content

Commit

Permalink
Merge pull request #1129 from LLNL/feature/bowen/structs
Browse files Browse the repository at this point in the history
Change from lambdas to structs for `Functional`
  • Loading branch information
white238 authored Jun 26, 2024
2 parents f398f91 + 93e5aa5 commit d10ee1c
Show file tree
Hide file tree
Showing 19 changed files with 507 additions and 397 deletions.
6 changes: 3 additions & 3 deletions src/serac/numerics/functional/boundary_integral_kernels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct QFunctionArgument<L2<p, c>, Dimension<dim>> {
/// @overload
SERAC_SUPPRESS_NVCC_HOSTDEVICE_WARNING
template <typename lambda, typename T, int... i>
SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, const tensor<double, 2>& x_q, const T& arg_tuple,
SERAC_HOST_DEVICE auto apply_qf_helper(const lambda& qf, double t, const tensor<double, 2>& x_q, const T& arg_tuple,
std::integer_sequence<int, i...>)
{
tensor<double, 2> J_q{};
Expand All @@ -86,7 +86,7 @@ SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, const tensor<doubl
/// @overload
SERAC_SUPPRESS_NVCC_HOSTDEVICE_WARNING
template <typename lambda, typename T, int... i>
SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, const tensor<double, 3>& x_q, const T& arg_tuple,
SERAC_HOST_DEVICE auto apply_qf_helper(const lambda& qf, double t, const tensor<double, 3>& x_q, const T& arg_tuple,
std::integer_sequence<int, i...>)
{
constexpr int dim = 3;
Expand All @@ -96,7 +96,7 @@ SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, const tensor<doubl

/// @overload
template <typename lambda, typename coords_type, typename... T>
SERAC_HOST_DEVICE auto apply_qf(lambda&& qf, double t, coords_type&& x_q, const serac::tuple<T...>& arg_tuple)
SERAC_HOST_DEVICE auto apply_qf(const lambda& qf, double t, const coords_type& x_q, const serac::tuple<T...>& arg_tuple)
{
return apply_qf_helper(qf, t, x_q, arg_tuple, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>{});
}
Expand Down
6 changes: 3 additions & 3 deletions src/serac/numerics/functional/detail/metaprogramming.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ struct integral_constant {

SERAC_SUPPRESS_NVCC_HOSTDEVICE_WARNING
template <typename lambda, int... i>
SERAC_HOST_DEVICE constexpr void for_constexpr(lambda&& f, integral_constant<i>... args)
SERAC_HOST_DEVICE constexpr void for_constexpr(const lambda& f, integral_constant<i>... args)
{
f(args...);
}

SERAC_SUPPRESS_NVCC_HOSTDEVICE_WARNING
template <int... n, typename lambda, typename... arg_types>
SERAC_HOST_DEVICE constexpr void for_constexpr(lambda&& f, std::integer_sequence<int, n...>, arg_types... args)
SERAC_HOST_DEVICE constexpr void for_constexpr(const lambda& f, std::integer_sequence<int, n...>, arg_types... args)
{
(detail::for_constexpr(f, args..., integral_constant<n>{}), ...);
}
Expand Down Expand Up @@ -94,7 +94,7 @@ SERAC_HOST_DEVICE constexpr void for_constexpr(lambda&& f, std::integer_sequence
*
*/
template <int... n, typename lambda>
SERAC_HOST_DEVICE constexpr void for_constexpr(lambda&& f)
SERAC_HOST_DEVICE constexpr void for_constexpr(const lambda& f)
{
detail::for_constexpr(f, std::make_integer_sequence<int, n>{}...);
}
12 changes: 6 additions & 6 deletions src/serac/numerics/functional/domain_integral_kernels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct QFunctionArgument<Hcurl<p>, Dimension<3>> {
/// @brief layer of indirection needed to unpack the entries of the argument tuple
SERAC_SUPPRESS_NVCC_HOSTDEVICE_WARNING
template <typename lambda, typename coords_type, typename T, typename qpt_data_type, int... i>
SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, coords_type&& x_q, qpt_data_type&& qpt_data,
SERAC_HOST_DEVICE auto apply_qf_helper(const lambda& qf, double t, const coords_type& x_q, qpt_data_type& qpt_data,
const T& arg_tuple, std::integer_sequence<int, i...>)
{
if constexpr (std::is_same<typename std::decay<qpt_data_type>::type, Nothing>::value) {
Expand All @@ -87,23 +87,23 @@ SERAC_HOST_DEVICE auto apply_qf_helper(lambda&& qf, double t, coords_type&& x_q,
* @param[inout] qpt_data The state information at the quadrature point
*/
template <typename lambda, typename coords_type, typename... T, typename qpt_data_type>
SERAC_HOST_DEVICE auto apply_qf(lambda&& qf, double t, coords_type&& x_q, qpt_data_type&& qpt_data,
SERAC_HOST_DEVICE auto apply_qf(const lambda& qf, double t, const coords_type& x_q, qpt_data_type& qpt_data,
const serac::tuple<T...>& arg_tuple)
{
return apply_qf_helper(qf, t, x_q, qpt_data, arg_tuple,
std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>{});
}

template <int i, int dim, typename... trials, typename lambda, typename qpt_data_type>
auto get_derivative_type(lambda qf, qpt_data_type&& qpt_data)
auto get_derivative_type(const lambda& qf, qpt_data_type qpt_data)
{
using qf_arguments = serac::tuple<typename QFunctionArgument<trials, serac::Dimension<dim>>::type...>;
return get_gradient(apply_qf(qf, double{}, serac::tuple<tensor<double, dim>, tensor<double, dim, dim>>{}, qpt_data,
make_dual_wrt<i>(qf_arguments{})));
};

template <typename lambda, int dim, int n, typename... T>
SERAC_HOST_DEVICE auto batch_apply_qf_no_qdata(lambda qf, double t, const tensor<double, dim, n>& x,
SERAC_HOST_DEVICE auto batch_apply_qf_no_qdata(const lambda& qf, double t, const tensor<double, dim, n>& x,
const tensor<double, dim, dim, n>& J, const T&... inputs)
{
using position_t = serac::tuple<tensor<double, dim>, tensor<double, dim, dim>>;
Expand All @@ -124,7 +124,7 @@ SERAC_HOST_DEVICE auto batch_apply_qf_no_qdata(lambda qf, double t, const tensor
}

template <typename lambda, int dim, int n, typename qpt_data_type, typename... T>
SERAC_HOST_DEVICE auto batch_apply_qf(lambda qf, double t, const tensor<double, dim, n>& x,
SERAC_HOST_DEVICE auto batch_apply_qf(const lambda& qf, double t, const tensor<double, dim, n>& x,
const tensor<double, dim, dim, n>& J, qpt_data_type* qpt_data, bool update_state,
const T&... inputs)
{
Expand Down Expand Up @@ -362,7 +362,7 @@ void element_gradient_kernel(ExecArrayView<double, 3, ExecutionSpace::CPU> dK, d

template <uint32_t wrt, int Q, mfem::Geometry::Type geom, typename signature, typename lambda_type, typename state_type,
typename derivative_type>
auto evaluation_kernel(signature s, lambda_type qf, const double* positions, const double* jacobians,
auto evaluation_kernel(signature s, const lambda_type& qf, const double* positions, const double* jacobians,
std::shared_ptr<QuadratureData<state_type>> qf_state,
std::shared_ptr<derivative_type> qf_derivatives, const int* elements, uint32_t num_elements)
{
Expand Down
18 changes: 9 additions & 9 deletions src/serac/numerics/functional/functional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ class Functional<test(trials...), exec> {
* and @a spatial_dim template parameter
* @param[inout] qdata The data for each quadrature point
*/
template <int dim, int... args, typename lambda, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, mfem::Mesh& domain,
template <int dim, int... args, typename Integrand, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, const Integrand& integrand, mfem::Mesh& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> qdata = NoQData)
{
if (domain.GetNE() == 0) return;
Expand All @@ -298,7 +298,7 @@ class Functional<test(trials...), exec> {

/// @overload
template <int dim, int... args, typename lambda, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, Domain& domain,
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, Domain& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> qdata = NoQData)
{
if (domain.mesh_.GetNE() == 0) return;
Expand All @@ -322,8 +322,8 @@ class Functional<test(trials...), exec> {
* @note The @p Dimension parameters are used to assist in the deduction of the @a geometry_dim
* and @a spatial_dim template parameter
*/
template <int dim, int... args, typename lambda>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, mfem::Mesh& domain)
template <int dim, int... args, typename Integrand>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, const Integrand& integrand, mfem::Mesh& domain)
{
auto num_bdr_elements = domain.GetNBE();
if (num_bdr_elements == 0) return;
Expand All @@ -337,7 +337,7 @@ class Functional<test(trials...), exec> {

/// @overload
template <int dim, int... args, typename lambda>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, const Domain& domain)
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, const Domain& domain)
{
auto num_bdr_elements = domain.mesh_.GetNBE();
if (num_bdr_elements == 0) return;
Expand All @@ -360,7 +360,7 @@ class Functional<test(trials...), exec> {
* @param[inout] data The data for each quadrature point
*/
template <int... args, typename lambda, typename qpt_data_type = Nothing>
void AddAreaIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain,
void AddAreaIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> data = NoQData)
{
AddDomainIntegral(Dimension<2>{}, which_args, integrand, domain, data);
Expand All @@ -376,15 +376,15 @@ class Functional<test(trials...), exec> {
* @param[inout] data The data for each quadrature point
*/
template <int... args, typename lambda, typename qpt_data_type = Nothing>
void AddVolumeIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain,
void AddVolumeIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> data = NoQData)
{
AddDomainIntegral(Dimension<3>{}, which_args, integrand, domain, data);
}

/// @brief alias for Functional::AddBoundaryIntegral(Dimension<2>{}, integrand, domain);
template <int... args, typename lambda>
void AddSurfaceIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain)
void AddSurfaceIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain)
{
AddBoundaryIntegral(Dimension<2>{}, which_args, integrand, domain);
}
Expand Down
14 changes: 7 additions & 7 deletions src/serac/numerics/functional/functional_qoi.inl
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public:
* and @a spatial_dim template parameter
*/
template <int dim, int... args, typename lambda, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, mfem::Mesh& mesh,
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, mfem::Mesh& mesh,
std::shared_ptr<QuadratureData<qpt_data_type>> qdata = NoQData)
{
if (mesh.GetNE() == 0) return;
Expand All @@ -174,7 +174,7 @@ public:

/// @overload
template <int dim, int... args, typename lambda, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, Domain& domain,
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, Domain& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> qdata = NoQData)
{
if (domain.mesh_.GetNE() == 0) return;
Expand All @@ -201,7 +201,7 @@ public:
* and @a spatial_dim template parameter
*/
template <int dim, int... args, typename lambda, typename qpt_data_type = void>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, mfem::Mesh& mesh)
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, mfem::Mesh& mesh)
{
auto num_bdr_elements = mesh.GetNBE();
if (num_bdr_elements == 0) return;
Expand All @@ -215,7 +215,7 @@ public:

/// @overload
template <int dim, int... args, typename lambda>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, const Domain& domain)
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, const Domain& domain)
{
auto num_bdr_elements = domain.mesh_.GetNBE();
if (num_bdr_elements == 0) return;
Expand All @@ -239,7 +239,7 @@ public:
* @brief Adds an area integral, i.e., over 2D elements in R^2
*/
template <int... args, typename lambda, typename qpt_data_type = Nothing>
void AddAreaIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain,
void AddAreaIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain,
std::shared_ptr<QuadratureData<qpt_data_type>>& data = NoQData)
{
AddDomainIntegral(Dimension<2>{}, which_args, integrand, domain, data);
Expand All @@ -256,15 +256,15 @@ public:
* @brief Adds a volume integral, i.e., over 3D elements in R^3
*/
template <int... args, typename lambda, typename qpt_data_type = Nothing>
void AddVolumeIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain,
void AddVolumeIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain,
std::shared_ptr<QuadratureData<qpt_data_type>>& data = NoQData)
{
AddDomainIntegral(Dimension<3>{}, which_args, integrand, domain, data);
}

/// @brief alias for Functional::AddBoundaryIntegral(Dimension<2>{}, integrand, domain);
template <int... args, typename lambda>
void AddSurfaceIntegral(DependsOn<args...> which_args, lambda&& integrand, mfem::Mesh& domain)
void AddSurfaceIntegral(DependsOn<args...> which_args, const lambda& integrand, mfem::Mesh& domain)
{
AddBoundaryIntegral(Dimension<2>{}, which_args, integrand, domain);
}
Expand Down
8 changes: 4 additions & 4 deletions src/serac/numerics/functional/integral.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ struct Integral {
*/
template <mfem::Geometry::Type geom, int Q, typename test, typename... trials, typename lambda_type,
typename qpt_data_type>
void generate_kernels(FunctionSignature<test(trials...)> s, Integral& integral, lambda_type&& qf,
void generate_kernels(FunctionSignature<test(trials...)> s, Integral& integral, const lambda_type& qf,
std::shared_ptr<QuadratureData<qpt_data_type> > qdata)
{
integral.geometric_factors_[geom] = GeometricFactors(integral.domain_, Q, geom);
Expand Down Expand Up @@ -236,7 +236,7 @@ void generate_kernels(FunctionSignature<test(trials...)> s, Integral& integral,
* @return Integral the initialized `Integral` object
*/
template <typename s, int Q, int dim, typename lambda_type, typename qpt_data_type>
Integral MakeDomainIntegral(const Domain& domain, lambda_type&& qf,
Integral MakeDomainIntegral(const Domain& domain, const lambda_type& qf,
std::shared_ptr<QuadratureData<qpt_data_type> > qdata,
std::vector<uint32_t> argument_indices)
{
Expand Down Expand Up @@ -273,7 +273,7 @@ Integral MakeDomainIntegral(const Domain& domain, lambda_type&& qf,
* @param qf the quadrature function
*/
template <mfem::Geometry::Type geom, int Q, typename test, typename... trials, typename lambda_type>
void generate_bdr_kernels(FunctionSignature<test(trials...)> s, Integral& integral, lambda_type&& qf)
void generate_bdr_kernels(FunctionSignature<test(trials...)> s, Integral& integral, const lambda_type& qf)
{
integral.geometric_factors_[geom] = GeometricFactors(integral.domain_, Q, geom, FaceType::BOUNDARY);
GeometricFactors& gf = integral.geometric_factors_[geom];
Expand Down Expand Up @@ -325,7 +325,7 @@ void generate_bdr_kernels(FunctionSignature<test(trials...)> s, Integral& integr
* @note this function is not meant to be called by users
*/
template <typename s, int Q, int dim, typename lambda_type>
Integral MakeBoundaryIntegral(const Domain& domain, lambda_type&& qf, std::vector<uint32_t> argument_indices)
Integral MakeBoundaryIntegral(const Domain& domain, const lambda_type& qf, std::vector<uint32_t> argument_indices)
{
FunctionSignature<s> signature;

Expand Down
8 changes: 4 additions & 4 deletions src/serac/numerics/functional/shape_aware_functional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ SERAC_HOST_DEVICE auto compute_boundary_area_correction(const position_type& X,
*/
template <typename lambda, typename coord_type, typename shape_type, typename space_types, typename trial_types,
typename correction_type, int... i>
SERAC_HOST_DEVICE auto apply_shape_aware_qf_helper(lambda&& qf, double t, const coord_type& position,
SERAC_HOST_DEVICE auto apply_shape_aware_qf_helper(const lambda& qf, double t, const coord_type& position,
const shape_type& shape, const space_types& space_tuple,
const trial_types& arg_tuple, const correction_type& correction,
std::integer_sequence<int, i...>)
Expand Down Expand Up @@ -244,7 +244,7 @@ SERAC_HOST_DEVICE auto apply_shape_aware_qf_helper(lambda&& qf, double t, const
*/
template <typename lambda, typename coord_type, typename state_type, typename shape_type, typename space_types,
typename trial_types, typename correction_type, int... i>
SERAC_HOST_DEVICE auto apply_shape_aware_qf_helper_with_state(lambda&& qf, double t, const coord_type& position,
SERAC_HOST_DEVICE auto apply_shape_aware_qf_helper_with_state(const lambda& qf, double t, const coord_type& position,
state_type& state, const shape_type& shape,
const space_types& space_tuple,
const trial_types& arg_tuple,
Expand Down Expand Up @@ -373,7 +373,7 @@ class ShapeAwareFunctional<shape, test(trials...), exec> {
* and @a spatial_dim template parameter
*/
template <int dim, int... args, typename lambda, typename domain_type, typename qpt_data_type = Nothing>
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, domain_type& domain,
void AddDomainIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, domain_type& domain,
std::shared_ptr<QuadratureData<qpt_data_type>> qdata = NoQData)
{
if constexpr (std::is_same_v<qpt_data_type, Nothing>) {
Expand Down Expand Up @@ -424,7 +424,7 @@ class ShapeAwareFunctional<shape, test(trials...), exec> {
* and @a spatial_dim template parameter
*/
template <int dim, int... args, typename lambda, typename domain_type>
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, lambda&& integrand, domain_type& domain)
void AddBoundaryIntegral(Dimension<dim>, DependsOn<args...>, const lambda& integrand, domain_type& domain)
{
functional_->AddBoundaryIntegral(
Dimension<dim>{}, DependsOn<0, (args + 1)...>{},
Expand Down
Loading

0 comments on commit d10ee1c

Please sign in to comment.