https://mooseframework.inl.gov
MultiAppMFEMShapeEvaluationTransfer.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 
13 
15 
18 {
20  params.addClassDescription("Transfers variable values from one MFEM application to another using "
21  "shape function evaluations.");
22  return params;
23 }
24 
26  InputParameters const & params)
27  : MFEMMultiAppTransfer(params)
28 {
29  checkValidTransferProblemTypes<Moose::FEBackend::MFEM, Moose::FEBackend::MFEM>();
30 }
31 
34 {
36 }
37 
40 {
42 }
43 
44 void
46 {
47  auto transformTargetPointsToSourceFrame =
48  [this](mfem::Vector & point_coordinates, const unsigned int dimension)
49  {
50  mooseAssert(dimension == 2 || dimension == 3, "Target finite element space must be 2D or 3D");
51 
52  const auto n_points = point_coordinates.Size() / dimension;
53  for (const auto i : make_range(n_points))
54  {
55  Point point_in_target_frame;
56  for (const auto d : make_range(dimension))
57  point_in_target_frame(d) = point_coordinates[i + d * n_points];
58 
59  const auto point_in_source_frame = mapPointToActiveSourceFrame(point_in_target_frame);
60  for (const auto d : make_range(dimension))
61  point_coordinates[i + d * n_points] = point_in_source_frame(d);
62  }
63  };
64 
65  // Get GridFunction from problem by name. For complex variables, return the real component.
66  auto getGridFunction = [&](MFEMProblem & problem,
67  const std::string & name,
68  bool & is_complex) -> mfem::ParGridFunction &
69  {
70  if (problem.getProblemData().gridfunctions.Has(name))
71  {
72  is_complex = false;
73  return *problem.getGridFunction(name);
74  }
76  {
77  is_complex = true;
78  return problem.getComplexGridFunction(name)->real();
79  }
80  mooseError("No real or complex variable named '", name, "' found.");
81  };
82 
83  for (const auto v : make_range(numToVar()))
84  {
85  bool is_from_complex{false};
86  mfem::ParGridFunction & from_gf =
87  getGridFunction(getActiveFromProblem(), getFromVarName(v), is_from_complex);
88  mfem::ParFiniteElementSpace & from_pfespace = *from_gf.ParFESpace();
89  from_pfespace.GetParMesh()->EnsureNodes();
90 
91  bool is_to_complex{false};
92  // Vector to store position coords of nodes/interpolation pts
93  mfem::Vector vxyz;
94  // Ordering of node coordinates x,y,z
95  mfem::Ordering::Type point_ordering = mfem::Ordering::Type::byNODES;
96  // Ordering of (vector) GridFunction data
97  mfem::Ordering::Type to_gf_ordering = mfem::Ordering::Type::byVDIM;
98  // Vector to store GridFunction values at interp. pts
99  mfem::Vector interp_vals;
100 
101  // Get points from target GridFunction on local rank
102  if (is_target_local)
103  {
104  mfem::ParGridFunction & to_gf =
105  getGridFunction(getActiveToProblem(), getToVarName(v), is_to_complex);
106  mfem::ParFiniteElementSpace & to_pfespace = *to_gf.ParFESpace();
107  to_pfespace.GetParMesh()->EnsureNodes();
108  // Generate list of points where the grid function will be evaluated
109  _mfem_projector.extractNodePositions(to_pfespace, vxyz, point_ordering);
110  // Evaluate source grid function at target points
111  const int dim = to_pfespace.GetParMesh()->Dimension();
112  transformTargetPointsToSourceFrame(vxyz, dim);
113  // Update ordering for interpolation
114  to_gf_ordering = to_pfespace.GetOrdering();
115  }
116 
117  // Evaluate source grid function at target points.
118  // Interpolation must be performed over all source ranks.
119  _mfem_interpolator.Setup(*from_gf.ParFESpace()->GetParMesh());
120  _mfem_interpolator.SetDefaultInterpolationValue(getMFEMOutOfMeshValue());
121  _mfem_interpolator.Interpolate(vxyz, from_gf, interp_vals, point_ordering, to_gf_ordering);
122 
123  // Project interpolated field onto target GridFunction data on the local rank
124  if (is_target_local)
125  {
126  mfem::ParGridFunction & to_gf =
127  getGridFunction(getActiveToProblem(), getToVarName(v), is_to_complex);
128  mfem::ParFiniteElementSpace & to_pfespace = *to_gf.ParFESpace();
129  _mfem_projector.projectNodalValues(interp_vals, to_gf_ordering, to_gf);
130  if (is_to_complex)
131  {
132  // Get remaining imaginary component of destination GridFunction
133  mfem::ParGridFunction & to_gf_im =
135  if (is_from_complex)
136  {
137  mfem::ParGridFunction & from_gf_im =
139  _mfem_interpolator.Interpolate(
140  vxyz, from_gf_im, interp_vals, point_ordering, to_pfespace.GetOrdering());
141  _mfem_projector.projectNodalValues(interp_vals, to_pfespace.GetOrdering(), to_gf_im);
142  }
143  else // Transfer from real variable to complex variable, so imag component zero
144  to_gf_im = 0.0;
145  }
146  }
147  }
148 }
149 
150 #endif
std::shared_ptr< mfem::ParGridFunction > getGridFunction(const std::string &name)
Definition: MFEMProblem.h:323
Virtual base class for MultiApp transfers to and/or from MFEMProblems.
virtual void transferVariables(bool is_target_local) override
Transfer all variables from active source problem to active destination problem.
void projectNodalValues(const mfem::Vector &nodal_vals, const mfem::Ordering::Type &nodal_val_ordering, mfem::ParGridFunction &gridfunction)
Project a vector of values provided at projection points (nodes) to set GridFunction DoFs...
Moose::MFEM::ComplexGridFunctions cmplx_gridfunctions
MFEMProblemData & getProblemData()
Method to get the current MFEMProblemData object storing the current data specifying the FE problem...
Definition: MFEMProblem.h:254
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:163
MultiApp transfer between MFEM variables, via shape function evaluation.
virtual FEProblemBase & getActiveFromProblem()
Getter for current problem containing source variables.
registerMooseObject("MooseApp", MultiAppMFEMShapeEvaluationTransfer)
virtual FEProblemBase & getActiveToProblem()
Getter for current problem containing destination variables.
mfem::FindPointsGSLIB _mfem_interpolator
Object to perform pointwise interpolation of source MFEM GridFunctions.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
unsigned int numToVar() const
Return for the number of destination variables.
MFEMNodalProjector _mfem_projector
Object to extract node positions and perform projections on destination MFEM GridFunctions.
MultiAppMFEMShapeEvaluationTransfer(InputParameters const &params)
void extractNodePositions(const mfem::ParFiniteElementSpace &fespace, mfem::Vector &node_positions, mfem::Ordering::Type &node_ordering)
Extract node positions from MFEM FESpace at which projection will take place.
virtual MFEMProblem & getActiveFromProblem() override
Set current MFEM problem to fetch source variables from.
std::shared_ptr< mfem::ParComplexGridFunction > getComplexGridFunction(const std::string &name)
Definition: MFEMProblem.h:331
mfem::real_t getMFEMOutOfMeshValue() const
Getter for default value for transfers evaluated at points outside source mesh.
const VariableName & getFromVarName(int i) const
Getter for source variable name.
static InputParameters validParams()
libMesh::Point mapPointToActiveSourceFrame(const Point &point_in_target_frame) const
Map a point in the active destination app frame to the active source app frame.
const VariableName & getToVarName(int i) const
Getter for destination variable name.
IntRange< T > make_range(T beg, T end)
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
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
virtual MFEMProblem & getActiveToProblem() override
Set current MFEM problem to fetch destination variables from.
Moose::MFEM::GridFunctions gridfunctions