10#ifdef MOOSE_MFEM_ENABLED
14#include "libmesh/mesh_function.h"
15#include "libmesh/parallel_algebra.h"
23 params.
addClassDescription(
"Transfers variable values from a libMesh based application to an "
24 "MFEM application, using shape function evaluations.");
32 checkValidTransferProblemTypes<Moose::FEBackend::MFEM, Moose::FEBackend::LibMesh>();
44 for (
const auto var_index : make_range(
numToVar()))
48 std::map<processor_id_type, std::vector<Point>> outgoing_points;
49 mfem::Vector interp_vals;
53 mfem::ParGridFunction & to_gf =
55 mfem::ParFiniteElementSpace & to_pfespace = *to_gf.ParFESpace();
56 if (to_gf.VectorDim() > 1)
57 mooseError(
"MultiApplibMeshToMFEMShapeEvaluationTransfer does not support transfers of "
58 "vector variables from libMesh to MFEM-based subapps");
60 mfem::Ordering::Type point_ordering;
65 const int dim = to_pfespace.GetParMesh()->Dimension();
66 const int nnodes = vxyz.Size() /
dim;
67 for (
const auto i : make_range(nnodes))
70 for (
const auto d : make_range(
dim))
71 point_in_target_frame(d) = vxyz[i + d * nnodes];
75 outgoing_points[i_proc].push_back(point_in_source_frame);
77 interp_vals.SetSize(nnodes);
86 mfem::ParGridFunction & to_gf =
88 mfem::Ordering::Type libmesh_interp_ordering(mfem::Ordering::Type::byNODES);
96 std::map<processor_id_type, std::vector<Point>> & outgoing_points,
97 const unsigned int var_index,
98 mfem::Vector & interp_vals)
105 System & from_sys = from_var.
sys().
system();
110 *from_sys.current_local_solution,
111 from_sys.get_dof_map(),
113 local_meshfuns.
init();
117 auto gather_functor =
118 [&](processor_id_type ,
119 const std::vector<Point> & incoming_points,
120 std::vector<std::pair<mfem::real_t, unsigned>> & vals_for_incoming_points)
122 vals_for_incoming_points.assign(incoming_points.size(), {0., 0});
124 for (
const auto i_pt : index_range(incoming_points))
127 for (
const auto & [elem, val] : map)
128 if (elem && elem->processor_id() == this->
processor_id())
130 vals_for_incoming_points[i_pt].first += val;
131 vals_for_incoming_points[i_pt].second++;
137 std::vector<unsigned> neighbor_elems(interp_vals.Size(), 0);
139 auto action_functor =
140 [&](processor_id_type ,
141 const std::vector<Point> & ,
142 const std::vector<std::pair<mfem::real_t, unsigned>> & vals_for_outgoing_points)
144 for (
const auto i : make_range(interp_vals.Size()))
146 const auto val = vals_for_outgoing_points[i].first;
147 const auto elems = vals_for_outgoing_points[i].second;
151 interp_vals(i) = val / (neighbor_elems[i] += elems);
153 interp_vals(i) = (interp_vals(i) * neighbor_elems[i] + val) / (neighbor_elems[i] += elems);
160 std::pair<mfem::real_t, unsigned> * dummy =
nullptr;
161 libMesh::Parallel::pull_parallel_vector_data(
162 comm(), outgoing_points, gather_functor, action_functor, dummy);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
registerMooseObject("MooseApp", MultiApplibMeshToMFEMShapeEvaluationTransfer)
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 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.
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.
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.
std::shared_ptr< mfem::ParGridFunction > getGridFunction(const std::string &name)
SystemBase & sys()
Get the system this variable is part of.
This class provides an interface for common operations on field variables of both FE and FV types wit...
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
MultiApp transfer from libMesh to MFEM variables, performed via evaluation of shape functions.
virtual void transferVariables(bool is_target_local) override
Transfer all variables from active source problem to active destination problem.
MFEMNodalProjector _mfem_projector
Object to extract node positions and perform projections on MFEM GridFunctions.
MultiApplibMeshToMFEMShapeEvaluationTransfer(InputParameters const ¶ms)
void interpolatelibMeshVariable(std::map< processor_id_type, std::vector< Point > > &outgoing_points, const unsigned int var_index, mfem::Vector &interp_vals)
Interpolate libMesh variable corresponding to var_index at target points for DoF evaluation.
static InputParameters validParams()
virtual MFEMProblem & getActiveToProblem() override
Set current MFEM problem to fetch destination variables from.
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
std::map< const Elem *, Number > discontinuous_value(const Point &p, const Real time=0.)
virtual void init() override
void enable_out_of_mesh_mode(const DenseVector< Number > &value)
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
unsigned int variable_number(std::string_view var) const