https://mooseframework.inl.gov
MFEMValueSamplerBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #ifdef MOOSE_MFEM_ENABLED
11 
12 #include "MFEMValueSamplerBase.h"
13 #include "MFEMProblem.h"
14 #include "MFEMVectorUtils.h"
15 
16 #include "mfem/fem/fespace.hpp"
17 
18 namespace
19 {
20 void
21 MFEMVectorToPostprocessorPoints(
22  const mfem::Vector & mfem_points,
23  std::vector<std::reference_wrapper<VectorPostprocessorValue>> & points,
24  const unsigned int num_dims,
25  const mfem::Ordering::Type ordering)
26 {
27  const unsigned int num_points = mfem_points.Size() / num_dims;
28  for (unsigned int i_point = 0; i_point < num_points; i_point++)
29  {
30  for (unsigned int i_dim = 0; i_dim < num_dims; i_dim++)
31  {
32  const size_t idx = Moose::MFEM::MFEMIndex(i_dim, i_point, num_dims, num_points, ordering);
33 
34  points[i_dim].get()[i_point] = mfem_points(idx);
35  }
36  }
37 }
38 }
39 
42 {
44 
45  MFEMExecutedObject::addRequiredDependencyParam<VariableName>(
46  params, "variable", "The names of the variables that this VectorPostprocessor operates on");
47  MooseEnum ordering("NODES VDIM", "VDIM", false);
48  params.addParam<MooseEnum>(
49  "point_ordering", ordering, "Ordering style to use for point vector DoFs.");
50 
51  return params;
52 }
53 
55  const std::vector<Point> & points)
56  : MFEMVectorPostprocessor(parameters),
57  _var_name(getParam<VariableName>("variable")),
58  _var(*getMFEMProblem().getGridFunction(_var_name)),
59  _mesh(const_cast<mfem::ParMesh &>(getMFEMProblem().getMFEMVariableMesh(_var_name))),
60  _finder(this->comm().get()),
61  _points_ordering(getParam<MooseEnum>("point_ordering") == "NODES" ? mfem::Ordering::byNODES
62  : mfem::Ordering::byVDIM),
63  _points(
64  Moose::MFEM::libMeshPointsToMFEMVector(points, _mesh.SpaceDimension(), _points_ordering)),
65  _interp_vals(points.size())
66 {
67  if (getMFEMProblem().mesh().shouldDisplace())
68  mooseError("MFEMValueSamplerBase does not yet support problems with displacement.");
69 
70  // set up points vector
71  _mesh.EnsureNodes();
72  _finder.Setup(_mesh);
73  _finder.FindPoints(_points, _points_ordering);
74 
75  // check all points were found
76  mfem::Array<unsigned int> point_codes = _finder.GetCode();
77  for (size_t i = 0; i < points.size(); i++)
78  {
79  if (point_codes[i] > 1)
80  {
81  mooseError("MFEMValueSamplerBase could not find point at ", points[i], ".");
82  }
83  }
84 
85  // declare points vectors for outputting
86  const auto mesh_dim = _mesh.SpaceDimension();
87  for (int i = 0; i < mesh_dim; i++)
88  {
89  std::reference_wrapper<VectorPostprocessorValue> declared_dim =
90  this->declareVector("x_" + std::to_string(i));
91  declared_dim.get().resize(points.size());
92  _declared_points.push_back(declared_dim);
93  }
94 
95  // declare value vectors for outputting
96  const auto val_dim = _var.VectorDim();
97  for (int i = 0; i < val_dim; i++)
98  {
99  std::reference_wrapper<VectorPostprocessorValue> declared_dim =
100  this->declareVector(_var_name + "_" + std::to_string(i));
101  declared_dim.get().resize(points.size());
102  _declared_vals.push_back(declared_dim);
103  }
104 }
105 
106 void
108 {
109  _finder.Interpolate(_var, _interp_vals);
110 }
111 
112 void
114 {
115  _interp_vals.HostReadWrite();
116  _points.HostReadWrite();
117 
118  const auto mesh_dim = _mesh.SpaceDimension();
119  MFEMVectorToPostprocessorPoints(_points, _declared_points, mesh_dim, _points_ordering);
120  const auto val_dims = _var.VectorDim();
121  const auto num_points = _declared_points[0].get().size();
122  const auto val_fespace_ordering = _var.FESpace()->GetOrdering();
123  for (int i_dim = 0; i_dim < val_dims; i_dim++)
124  {
125  for (size_t i_point = 0; i_point < num_points; i_point++)
126  {
127  const auto mfem_idx =
128  Moose::MFEM::MFEMIndex(i_dim, i_point, val_dims, num_points, val_fespace_ordering);
129  _declared_vals[i_dim].get()[i_point] = _interp_vals[mfem_idx];
130  }
131  }
132 }
133 
134 #endif // MOOSE_MFEM_ENABLED
MFEMProblem & getMFEMProblem()
Return the owning MFEM problem.
Definition: MFEMObject.h:45
static InputParameters validParams()
virtual void execute() override
Perform the interpolation in FindPointsGSLIB.
mfem::Vector libMeshPointsToMFEMVector(const std::vector< libMesh::Point > &points, const unsigned int num_dims, const mfem::Ordering::Type ordering)
Convert a vector of libMesh::Point objects to an mfem::Vector containing all points, given an ordering.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual void finalize() override
Store the result of the interpolation.
std::vector< std::reference_wrapper< VectorPostprocessorValue > > _declared_vals
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
const mfem::GridFunction & _var
std::size_t MFEMIndex(const std::size_t i_dim, const std::size_t i_point, const std::size_t num_dims, const std::size_t num_points, const mfem::Ordering::Type ordering)
Convert an index of a vector of libMesh::Points to an MFEM vector index, given an MFEM ordering...
const VariableName & _var_name
mfem::FindPointsGSLIB _finder
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
mfem::Ordering::Type _points_ordering
static InputParameters validParams()
std::vector< std::reference_wrapper< VectorPostprocessorValue > > _declared_points
MFEMValueSamplerBase(const InputParameters &parameters, const std::vector< Point > &points)
const Elem & get(const ElemType type_in)
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)