15 #include "serac/numerics/functional/geometric_factors.hpp"
16 #include "serac/numerics/functional/function_signature.hpp"
17 #include "serac/numerics/functional/domain_integral_kernels.hpp"
18 #include "serac/numerics/functional/boundary_integral_kernels.hpp"
19 #include "serac/numerics/functional/differentiate_wrt.hpp"
40 std::size_t num_trial_spaces = trial_space_indices.size();
42 jvp_.resize(num_trial_spaces);
45 for (uint32_t i = 0; i < num_trial_spaces; i++) {
65 void Mult(
double t,
const std::vector<mfem::BlockVector>& input_E, mfem::BlockVector& output_E,
66 uint32_t differentiation_index,
bool update_state)
const
74 for (
auto& [geometry, func] : kernels) {
79 func(t, inputs, output_E.GetBlock(geometry).ReadWrite(), update_state);
93 void GradientMult(
const mfem::BlockVector& input_E, mfem::BlockVector& output_E, uint32_t differentiation_index)
const
100 func(input_E.GetBlock(geometry).Read(), output_E.GetBlock(geometry).ReadWrite());
113 uint32_t differentiation_index)
const
118 func(
view(K_e[geometry]));
127 using eval_func = std::function<void(
double,
const std::vector<const double*>&,
double*,
bool)>;
139 std::vector<std::map<mfem::Geometry::Type, jacobian_vector_product_func> >
jvp_;
184 template <mfem::Geometry::Type geom,
int Q,
typename test,
typename... trials,
typename lambda_type,
185 typename qpt_data_type>
193 const double* positions = gf.
X.Read();
194 const double* jacobians = gf.
J.Read();
195 const int* elements = &integral.
domain_.
get(geom)[0];
196 const uint32_t num_elements = uint32_t(gf.
num_elements);
199 std::shared_ptr<zero> dummy_derivatives;
200 integral.
evaluation_[geom] = domain_integral::evaluation_kernel<NO_DIFFERENTIATION, Q, geom>(
201 s, qf, positions, jacobians, qdata, dummy_derivatives, elements, num_elements);
203 constexpr std::size_t num_args = s.num_args;
204 [[maybe_unused]]
static constexpr
int dim =
dimension_of(geom);
205 for_constexpr<num_args>([&](
auto index) {
211 using derivative_type = decltype(domain_integral::get_derivative_type<index, dim, trials...>(qf, qpt_data_type{}));
212 auto ptr = accelerator::make_shared_array<ExecutionSpace::CPU, derivative_type>(num_elements * qpts_per_element);
214 integral.
evaluation_with_AD_[index][geom] = domain_integral::evaluation_kernel<index, Q, geom>(
215 s, qf, positions, jacobians, qdata, ptr, elements, num_elements);
217 integral.
jvp_[index][geom] =
218 domain_integral::jacobian_vector_product_kernel<index, Q, geom>(s, ptr, elements, num_elements);
220 domain_integral::element_gradient_kernel<index, Q, geom>(s, ptr, elements, num_elements);
238 template <
typename s,
int Q,
int dim,
typename lambda_type,
typename qpt_data_type>
241 std::vector<uint32_t> argument_indices)
245 SLIC_ERROR_IF(domain.
type_ != Domain::Type::Elements,
"Error: trying to evaluate a domain integral over a boundary");
247 Integral integral(domain, argument_indices);
249 if constexpr (dim == 2) {
250 generate_kernels<mfem::Geometry::TRIANGLE, Q>(signature, integral, qf, qdata);
251 generate_kernels<mfem::Geometry::SQUARE, Q>(signature, integral, qf, qdata);
254 if constexpr (dim == 3) {
255 generate_kernels<mfem::Geometry::TETRAHEDRON, Q>(signature, integral, qf, qdata);
256 generate_kernels<mfem::Geometry::CUBE, Q>(signature, integral, qf, qdata);
275 template <mfem::Geometry::Type geom,
int Q,
typename test,
typename... trials,
typename lambda_type>
282 const double* positions = gf.
X.Read();
283 const double* jacobians = gf.
J.Read();
284 const uint32_t num_elements = uint32_t(gf.
num_elements);
286 const int* elements = &gf.
elements[0];
288 std::shared_ptr<zero> dummy_derivatives;
289 integral.
evaluation_[geom] = boundary_integral::evaluation_kernel<NO_DIFFERENTIATION, Q, geom>(
290 s, qf, positions, jacobians, dummy_derivatives, elements, num_elements);
292 constexpr std::size_t num_args = s.num_args;
293 [[maybe_unused]]
static constexpr
int dim =
dimension_of(geom);
294 for_constexpr<num_args>([&](
auto index) {
300 using derivative_type = decltype(boundary_integral::get_derivative_type<index, dim, trials...>(qf));
301 auto ptr = accelerator::make_shared_array<ExecutionSpace::CPU, derivative_type>(num_elements * qpts_per_element);
304 boundary_integral::evaluation_kernel<index, Q, geom>(s, qf, positions, jacobians, ptr, elements, num_elements);
306 integral.
jvp_[index][geom] =
307 boundary_integral::jacobian_vector_product_kernel<index, Q, geom>(s, ptr, elements, num_elements);
309 boundary_integral::element_gradient_kernel<index, Q, geom>(s, ptr, elements, num_elements);
327 template <
typename s,
int Q,
int dim,
typename lambda_type>
332 SLIC_ERROR_IF(domain.
type_ != Domain::Type::BoundaryElements,
333 "Error: trying to evaluate a boundary integral over a non-boundary domain of integration");
335 Integral integral(domain, argument_indices);
337 if constexpr (dim == 1) {
338 generate_bdr_kernels<mfem::Geometry::SEGMENT, Q>(signature, integral, qf);
341 if constexpr (dim == 2) {
342 generate_bdr_kernels<mfem::Geometry::TRIANGLE, Q>(signature, integral, qf);
343 generate_bdr_kernels<mfem::Geometry::SQUARE, Q>(signature, integral, qf);
This file contains the interface used for initializing/terminating any hardware accelerator-related f...
Accelerator functionality.
Integral MakeBoundaryIntegral(const Domain &domain, lambda_type &&qf, std::vector< uint32_t > argument_indices)
function to generate kernels held by an Integral object of type "Boundary", for all element types
constexpr int num_quadrature_points(mfem::Geometry::Type g, int Q)
return the number of quadrature points in a Gauss-Legendre rule with parameter "Q"
axom::Array< T, dim, detail::execution_to_memory_v< space > > ExecArray
Alias for an Array corresponding to a particular ExecutionSpace.
void generate_bdr_kernels(FunctionSignature< test(trials...)> s, Integral &integral, lambda_type &&qf)
function to generate kernels held by an Integral object of type "BoundaryDomain", with a specific ele...
auto view(axom::Array< T, dim, space > &arr)
convenience function for creating a view of an axom::Array type
Integral MakeDomainIntegral(const Domain &domain, lambda_type &&qf, std::shared_ptr< QuadratureData< qpt_data_type > > qdata, std::vector< uint32_t > argument_indices)
function to generate kernels held by an Integral object of type "Domain", for all element types
void generate_kernels(FunctionSignature< test(trials...)> s, Integral &integral, lambda_type &&qf, std::shared_ptr< QuadratureData< qpt_data_type > > qdata)
function to generate kernels held by an Integral object of type "Domain", with a specific element typ...
axom::ArrayView< T, dim, detail::execution_to_memory_v< space > > ExecArrayView
Alias for an ArrayView corresponding to a particular ExecutionSpace.
constexpr int dimension_of(mfem::Geometry::Type g)
Returns the dimension of an element geometry.
a class for representing a geometric region that can be used for integration
Type type_
whether the elements in this domain are on the boundary or not
const std::vector< int > & get(mfem::Geometry::Type geom) const
get elements by geometry type
a class that computes and stores positions and jacobians at each quadrature point
std::size_t num_elements
the number of elements in the domain
std::vector< int > elements
list of element indices that are part of the associated domain
mfem::Vector J
Jacobians of the element transformations at all quadrature points.
mfem::Vector X
Mapped (physical) coordinates of all quadrature points.
a class for representing a Integral calculations and their derivatives
Domain domain_
information about which elements to integrate over
std::vector< uint32_t > active_trial_spaces_
a list of the trial spaces that take part in this integrand
std::map< uint32_t, uint32_t > functional_to_integral_index_
a way of translating between the indices used by Functional and Integral to refer to the same trial s...
std::vector< std::map< mfem::Geometry::Type, eval_func > > evaluation_with_AD_
kernels for integral evaluation + derivative w.r.t. specified argument over each type of element
std::map< mfem::Geometry::Type, GeometricFactors > geometric_factors_
the spatial positions and jacobians (dx_dxi) for each element type and quadrature point
std::function< void(ExecArrayView< double, 3, ExecutionSpace::CPU >)> grad_func
signature of element gradient kernel
static constexpr std::size_t num_types
the number of different kinds of integration domains
std::function< void(const double *, double *)> jacobian_vector_product_func
signature of element jvp kernel
Integral(const Domain &d, std::vector< uint32_t > trial_space_indices)
Construct an "empty" Integral object, whose kernels are to be initialized later in one of the Make***...
std::vector< std::map< mfem::Geometry::Type, grad_func > > element_gradient_
kernels for calculation of element jacobians
void ComputeElementGradients(std::map< mfem::Geometry::Type, ExecArray< double, 3, ExecutionSpace::CPU > > &K_e, uint32_t differentiation_index) const
evaluate the jacobian (with respect to some trial space) of this integral
std::map< mfem::Geometry::Type, eval_func > evaluation_
kernels for integral evaluation over each type of element
std::vector< std::map< mfem::Geometry::Type, jacobian_vector_product_func > > jvp_
kernels for jacobian-vector product of integral calculation
void Mult(double t, const std::vector< mfem::BlockVector > &input_E, mfem::BlockVector &output_E, uint32_t differentiation_index, bool update_state) const
evaluate the integral, optionally storing q-function derivatives with respect to a specific trial spa...
std::function< void(double, const std::vector< const double * > &, double *, bool)> eval_func
signature of integral evaluation kernel
void GradientMult(const mfem::BlockVector &input_E, mfem::BlockVector &output_E, uint32_t differentiation_index) const
evaluate the jacobian(with respect to some trial space)-vector product of this integral
A class for storing and access user-defined types at quadrature points.