https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiAppMFEMTolibMeshShapeEvaluationTransfer.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#include "MFEMVectorUtils.h"
14#include "libmesh/mesh_function.h"
15
17
20{
22 params.addClassDescription("Transfers variable values from an MFEM based application to a "
23 "libMesh application, using shape function evaluations.");
24 return params;
25}
26
28 InputParameters const & params)
29 : MFEMMultiAppTransfer(params), _mfem_interpolator(this->comm().get())
30{
31 checkValidTransferProblemTypes<Moose::FEBackend::LibMesh, Moose::FEBackend::MFEM>();
32}
33
39
41void
43 libMesh::System & to_sys,
44 const MooseVariableFieldBase & to_var,
45 std::vector<Point> & outgoing_libmesh_points)
46{
47 // libMesh mesh
48 const MeshBase & to_mesh = getActiveToProblem().mesh(_displaced_target_mesh).getMesh();
49 auto var_num = to_var.number();
50 auto sys_num = to_sys.number();
51 auto & fe_type = to_var.feType();
52 bool is_nodal = to_var.isNodal();
53
54 // Populate set of points
55 if (fe_type.order > CONSTANT && !is_nodal)
56 mooseError("Transfers of non-nodal FEs from MFEM to libMesh with order higher than "
57 "CONSTANT are not supported.");
58 else if (is_nodal)
59 {
60 // Consider nodes the variable has dofs at.
61 for (const auto & node : to_mesh.local_node_ptr_range())
62 if (node->n_dofs(sys_num, var_num))
63 outgoing_libmesh_points.push_back(*node);
64 }
65 else // Elemental, constant monomial
66 {
67 // Consider elements the variable has dofs at.
68 for (const auto & elem : as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
69 if (elem->n_dofs(sys_num, var_num))
70 outgoing_libmesh_points.push_back(elem->vertex_average());
71 }
72}
73
75void
77 libMesh::System & to_sys, const MooseVariableFieldBase & to_var, mfem::Vector & interp_vals)
78{
79 // libMesh mesh
80 const MeshBase & to_mesh = getActiveToProblem().mesh(_displaced_target_mesh).getMesh();
81 auto var_num = to_var.number();
82 auto sys_num = to_sys.number();
83 auto & fe_type = to_var.feType();
84 bool is_nodal = to_var.isNodal();
85
86 unsigned int mfem_point_index = 0;
87 if (fe_type.order > CONSTANT && !is_nodal)
88 mooseError("Transfers of non-nodal FEs from MFEM to libMesh with order higher than "
89 "CONSTANT are not supported.");
90 else if (is_nodal)
91 {
92 // Consider nodes the variable has dofs at.
93 for (const auto & node : to_mesh.local_node_ptr_range())
94 if (node->n_dofs(sys_num, var_num))
95 {
96 const auto dof_object_id = node->id();
97 const DofObject * dof_object = to_mesh.node_ptr(dof_object_id);
98 const auto dof = dof_object->dof_number(sys_num, var_num, 0);
99 const auto val = interp_vals[mfem_point_index];
100 to_sys.solution->set(dof, val);
101 mfem_point_index++;
102 }
103 }
104 else // Elemental, constant monomial
105 {
106 // Consider elements the variable has dofs at.
107 for (const auto & elem : as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
108 if (elem->n_dofs(sys_num, var_num))
109 {
110 const auto dof_object_id = elem->id();
111 const DofObject * dof_object = to_mesh.elem_ptr(dof_object_id);
112 const auto dof = dof_object->dof_number(sys_num, var_num, 0);
113 const auto val = interp_vals[mfem_point_index];
114 to_sys.solution->set(dof, val);
115 mfem_point_index++;
116 }
117 }
118 to_sys.solution->close();
119 // Sync local solutions
120 to_sys.update();
121}
122
123void
125{
126 // Send from MFEM problem to libMesh problem
127 for (const auto var_index : make_range(numToVar()))
128 {
129 // Declare source variable alias and construct vectors to store interpolation points and vals
130 auto & from_var = *getActiveFromProblem().getGridFunction(getFromVarName(var_index));
131 if (from_var.VectorDim() > 1)
132 mooseError("MultiAppMFEMTolibMeshShapeEvaluationTransfer does not support transfers of "
133 "vector variables from MFEM to libMesh-based subapps");
134 from_var.ParFESpace()->GetParMesh()->EnsureNodes();
135 // Ordering of interpolated MFEM output, chosen to match libMesh ordering
136 const mfem::Ordering::Type ordering = mfem::Ordering::byVDIM;
137 mfem::Vector interp_vals;
138 mfem::Vector outgoing_mfem_points;
139
140 // If target libMesh app is on the current rank, update the set of interpolation
141 // points with the libMesh variable's set
142 if (is_target_local)
143 {
144 // Declare aliases for convenience
145 FEProblemBase & to_problem = getActiveToProblem();
146 const MooseVariableFieldBase & to_var(
147 to_problem.getVariable(0,
148 getToVarName(var_index),
151 const auto & to_var_name = getToVarName(var_index);
152 auto & es = getlibMeshEquationSystem(to_problem, _displaced_target_mesh);
153 System & to_sys = *find_sys(es, to_var_name);
154 // Extract set of target points in libMesh mesh to perform interpolation of MFEM variable at
155 std::vector<Point> outgoing_libmesh_points;
156 extractlibMeshNodePositions(to_sys, to_var, outgoing_libmesh_points);
157 const MeshBase & to_mesh = to_problem.mesh(_displaced_target_mesh).getMesh();
158 // Perform interpolation of MFEM variable
159 for (auto & point : outgoing_libmesh_points)
160 point = mapPointToActiveSourceFrame(point);
161 outgoing_mfem_points = Moose::MFEM::libMeshPointsToMFEMVector(
162 outgoing_libmesh_points, to_mesh.mesh_dimension(), ordering);
163 }
164
165 // MFEM interpolation using FindPointsGSLib::Interpolate must be over all ranks
166 // of the MFEM variable's MPI communicator
167 _mfem_interpolator.SetDefaultInterpolationValue(getMFEMOutOfMeshValue());
168 _mfem_interpolator.Interpolate(*from_var.ParFESpace()->GetParMesh(),
169 outgoing_mfem_points,
170 from_var,
171 interp_vals,
172 ordering);
173
174 // If target libMesh variable exists on the current rank, update the set of local
175 // DoFs of the target libMesh variable using the interpolated MFEM values
176 if (is_target_local)
177 {
178 // Declare aliases for convenience
179 FEProblemBase & to_problem = getActiveToProblem();
180 const MooseVariableFieldBase & to_var(
181 to_problem.getVariable(0,
182 getToVarName(var_index),
185 const auto & to_var_name = getToVarName(var_index);
186 // Get undisplaced system for writing transferred variable to
187 auto & out_es = getlibMeshEquationSystem(to_problem, false);
188 auto & out_sys = *find_sys(out_es, to_var_name);
189
190 // Project interpolated values at destination nodes onto destination variables to set DoFs
191 projectlibMeshNodalValues(out_sys, to_var, interp_vals);
192 }
193 }
194}
195
196#endif
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObject("MooseApp", MultiAppMFEMTolibMeshShapeEvaluationTransfer)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
virtual MooseMesh & mesh() override
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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 base class for MultiApp transfers to and/or from MFEMProblems.
const VariableName & getToVarName(int i) const
Getter for destination variable name.
unsigned int numToVar() const
Return for the number of destination variables.
static InputParameters validParams()
const VariableName & getFromVarName(int i) const
Getter for source variable name.
libMesh::EquationSystems & getlibMeshEquationSystem(FEProblemBase &problem, bool use_displaced) const
Get libMesh EquationSystem, which may or may not be displaced.
virtual FEProblemBase & getActiveToProblem()
Getter for current problem containing destination variables.
mfem::real_t getMFEMOutOfMeshValue() const
Getter for default value for transfers evaluated at points outside source mesh.
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.
virtual FEProblemBase & getActiveFromProblem()
Getter for current problem containing source variables.
std::shared_ptr< mfem::ParGridFunction > getGridFunction(const std::string &name)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
const libMesh::FEType & feType() const
Get the type of finite element object.
virtual bool isNodal() const
Is this variable nodal.
unsigned int number() const
Get variable number coming from libMesh.
This class provides an interface for common operations on field variables of both FE and FV types wit...
MultiApp transfer from MFEM to libMesh variables, performed via evaluation of shape functions.
virtual void transferVariables(bool is_target_local) override
Transfer all variables from active MFEM source problem to active libMesh destination problem.
virtual MFEMProblem & getActiveFromProblem() override
Set current MFEM problem to fetch source variables from.
mfem::FindPointsGSLIB _mfem_interpolator
Object to perform pointwise interpolation of source MFEM GridFunctions.
void projectlibMeshNodalValues(libMesh::System &to_sys, const MooseVariableFieldBase &to_var, mfem::Vector &interp_vals)
Set DoFs of destination libMesh variable via projection, using a vector of interpolated values.
void extractlibMeshNodePositions(libMesh::System &to_sys, const MooseVariableFieldBase &to_var, std::vector< Point > &outgoing_libmesh_points)
Extract all target points of the destination libMesh variable, needed to set DoFs in transfer.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
static libMesh::System * find_sys(libMesh::EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
Definition Transfer.C:91
std::unique_ptr< NumericVector< Number > > solution
virtual void update()
unsigned int number() const
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,...
@ VAR_FIELD_ANY
Definition MooseTypes.h:781
@ VAR_ANY
Definition MooseTypes.h:772