Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
finite_element_state.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
14 #pragma once
15 
16 #include <functional>
17 #include <memory>
18 #include <optional>
19 #include <type_traits>
20 #include <utility>
21 
22 #include "mfem.hpp"
27 
28 namespace smith {
29 
30 namespace detail {
34 template <int dim>
35 void setMfemVectorFromTensorOrDouble(mfem::Vector& v_mfem, const tensor<double, dim>& v)
36 {
37  SLIC_ERROR_IF(v_mfem.Size() != dim, "Cannot copy tensor into an MFEM Vector with incompatible size.");
38  for (int i = 0; i < dim; i++) v_mfem(i) = v[i];
39 }
40 
44 inline void setMfemVectorFromTensorOrDouble(mfem::Vector& v_mfem, double v)
45 {
46  SLIC_ERROR_IF(v_mfem.Size() != 1, "Mfem Vector is not a singleton.");
47  v_mfem = v;
48 }
49 
53 template <typename Ret, typename Arg, typename... Rest>
54 Arg first_argument_helper(Ret (*)(Arg, Rest...));
55 
59 template <typename Ret, typename F, typename Arg, typename... Rest>
60 Arg first_argument_helper(Ret (F::*)(Arg, Rest...));
61 
65 template <typename Ret, typename F, typename Arg, typename... Rest>
66 Arg first_argument_helper(Ret (F::*)(Arg, Rest...) const);
67 
71 template <typename F>
72 decltype(first_argument_helper(&F::operator())) first_argument_helper(F);
73 
77 template <typename T>
78 using first_argument = std::decay_t<decltype(first_argument_helper(std::declval<T>()))>;
79 
83 template <typename Callable>
84 auto evaluateTensorFunctionOnMfemVector(const mfem::Vector& X_mfem, Callable&& f)
85 {
87  SLIC_ERROR_IF(X_mfem.Size() != size(X),
88  "Size of tensor in callable does not match spatial dimension of MFEM Vector.");
89  for (int i = 0; i < X_mfem.Size(); i++) X[i] = X_mfem[i];
90  return f(X);
91 }
92 
93 } // namespace detail
94 
98 inline bool is_scalar_valued(const GeneralCoefficient& coef)
99 {
100  return holds_alternative<std::shared_ptr<mfem::Coefficient>>(coef);
101 }
102 
106 inline bool is_vector_valued(const GeneralCoefficient& coef)
107 {
108  return holds_alternative<std::shared_ptr<mfem::VectorCoefficient>>(coef);
109 }
110 
117  public:
119  using mfem::Vector::Print;
120 
127 
134 
142  {
144  return *this;
145  }
146 
154  {
156  return *this;
157  }
158 
165  FiniteElementState& operator=(const mfem::HypreParVector& rhs)
166  {
168  return *this;
169  }
170 
177  FiniteElementState& operator=(const mfem::Vector& rhs)
178  {
180  return *this;
181  }
182 
190  {
192  return *this;
193  }
194 
204  void fillGridFunction(mfem::ParGridFunction& grid_function) const { grid_function.SetFromTrueDofs(*this); }
205 
216  void setFromGridFunction(const mfem::ParGridFunction& grid_function) { grid_function.GetTrueDofs(*this); }
217 
227  void project(mfem::VectorCoefficient& coef, mfem::Array<int>& dof_list);
228 
239  void project(mfem::Coefficient& coef, mfem::Array<int>& dof_list, std::optional<int> component = {});
240 
248  void project(const GeneralCoefficient& coef);
249 
251  void project(mfem::Coefficient& coef);
252 
254  void project(mfem::VectorCoefficient& coef);
255 
265  void projectOnBoundary(mfem::Coefficient& coef, const mfem::Array<int>& markers);
266 
268  void projectOnBoundary(mfem::VectorCoefficient& coef, const mfem::Array<int>& markers);
269 
271  void project(mfem::Coefficient& coef, const Domain& d);
272 
274  void project(mfem::VectorCoefficient& coef, const Domain& d);
275 
298  template <typename FieldFunction>
299  void setFromFieldFunction(FieldFunction&& field_function)
300  {
301  auto evaluate_mfem = [&field_function](const mfem::Vector& X_mfem, mfem::Vector& u_mfem) {
302  auto u = detail::evaluateTensorFunctionOnMfemVector(X_mfem, field_function);
303  detail::setMfemVectorFromTensorOrDouble(u_mfem, u);
304  };
305 
306  mfem::VectorFunctionCoefficient coef(space_->GetVDim(), evaluate_mfem);
307  project(coef);
308  }
309 
315  mfem::ParGridFunction& gridFunction() const;
316 
317  protected:
324  mutable std::unique_ptr<mfem::ParGridFunction> grid_func_;
325 };
326 
334 double norm(const FiniteElementState& state, const double p = 2);
335 
343 double computeL2Error(const FiniteElementState& state, mfem::VectorCoefficient& exact_solution);
344 
352 double computeL2Error(const FiniteElementState& state, mfem::Coefficient& exact_solution);
353 
354 } // namespace smith
Class for encapsulating the critical MFEM components of a primal finite element field.
mfem::ParGridFunction & gridFunction() const
Construct a grid function from the finite element state true vector.
FiniteElementState & operator=(const mfem::Vector &rhs)
Copy assignment with mfem::Vector.
FiniteElementState & operator=(const mfem::HypreParVector &rhs)
Copy assignment with HypreParVector.
void fillGridFunction(mfem::ParGridFunction &grid_function) const
Fill a user-provided grid function based on the underlying true vector.
void setFromFieldFunction(FieldFunction &&field_function)
Set state as interpolant of an analytical function.
FiniteElementState & operator=(const FiniteElementState &rhs)
Copy assignment.
void projectOnBoundary(mfem::Coefficient &coef, const mfem::Array< int > &markers)
Project a coefficient on a specific set of marked boundaries.
std::unique_ptr< mfem::ParGridFunction > grid_func_
An optional container for a grid function (L-vector) view of the finite element state.
FiniteElementState(FiniteElementState &&rhs)
Move construct a new Finite Element State object.
FiniteElementState & operator=(double rhs)
Copy assignment with double.
FiniteElementState & operator=(FiniteElementState &&rhs)
Move assignment.
FiniteElementState(const FiniteElementState &rhs)
Copy constructor.
void project(mfem::VectorCoefficient &coef, mfem::Array< int > &dof_list)
Project a vector coefficient onto a set of dofs.
void setFromGridFunction(const mfem::ParGridFunction &grid_function)
Initialize the true vector in the FiniteElementState based on an input grid function.
Class for encapsulating the data associated with a vector derived from a MFEM finite element space....
std::unique_ptr< mfem::ParFiniteElementSpace > space_
Handle to the mfem::ParFiniteElementSpace, which is owned by MFEMSidreDataCollection.
FiniteElementVector & operator=(const FiniteElementVector &rhs)
Copy assignment.
FiniteElementVector(const mfem::ParFiniteElementSpace &space, const std::string &name="")
Minimal constructor for a FiniteElementVector given a finite element space.
many of the functions in this file amount to extracting element indices from an mesh_t like
void setMfemVectorFromTensorOrDouble(mfem::Vector &v_mfem, const tensor< double, dim > &v)
Helper function to copy a tensor into an mfem Vector.
decltype(first_argument_helper(&F::operator())) first_argument_helper(F)
std::decay_t< decltype(first_argument_helper(std::declval< T >()))> first_argument
This file contains the declaration of structure that manages vectors derived from an MFEM finite elem...
Accelerator functionality.
Definition: smith.cpp:36
variant< std::shared_ptr< mfem::Coefficient >, std::shared_ptr< mfem::VectorCoefficient > > GeneralCoefficient
A sum type for encapsulating either a scalar or vector coeffient.
constexpr SMITH_HOST_DEVICE auto norm(const isotropic_tensor< T, m, m > &I)
compute the Frobenius norm (sqrt(tr(dot(transpose(I), I)))) of an isotropic tensor
constexpr SMITH_HOST_DEVICE int size(const tensor< T, n... > &)
returns the total number of stored values in a tensor
Definition: tensor.hpp:1932
bool is_vector_valued(const GeneralCoefficient &coef)
convenience function for querying the type stored in a GeneralCoefficient
bool is_scalar_valued(const GeneralCoefficient &coef)
convenience function for querying the type stored in a GeneralCoefficient
double computeL2Error(const FiniteElementState &state, mfem::VectorCoefficient &exact_solution)
Find the L2 norm of the error of a vector-valued finite element state with respect to an exact soluti...
Implementation of the tensor class used by Functional.
This file contains the declaration of a two-element variant type.