https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MFEMNodalProjector.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 "MFEMNodalProjector.h"
13#include "MFEMVectorUtils.h"
14#include "MooseError.h"
15
16void
17MFEMNodalProjector::extractNodePositions(const mfem::ParFiniteElementSpace & fespace,
18 mfem::Vector & node_positions,
19 mfem::Ordering::Type & node_ordering)
20{
21 const int nelem = fespace.GetParMesh()->GetNE();
22 const int dim = fespace.GetParMesh()->Dimension();
23
24 // Find total number of local nodes/interpolation points
25 int nnodes = 0;
26 for (const auto i : make_range(nelem))
27 nnodes += fespace.GetFE(i)->GetNodes().GetNPoints();
28
29 node_positions.SetSize(nnodes * dim);
30
31 int nodal_offset = 0;
32 for (const auto i : make_range(nelem))
33 {
34 const mfem::IntegrationRule ir = fespace.GetFE(i)->GetNodes();
35 const int nqpt = ir.GetNPoints();
36
37 mfem::DenseMatrix pos;
38 fespace.GetElementTransformation(i)->Transform(ir, pos);
39 mfem::Vector row;
40
41 for (const auto d : make_range(dim))
42 {
43 row.SetDataAndSize(node_positions.GetData() + nodal_offset + d * nnodes, nqpt);
44 pos.GetRow(d, row);
45 }
46
47 nodal_offset += nqpt;
48 }
49 node_ordering = mfem::Ordering::Type::byNODES;
50}
51
52void
53MFEMNodalProjector::projectNodalValues(const mfem::Vector & nodal_vals,
54 const mfem::Ordering::Type & nodal_val_ordering,
55 mfem::ParGridFunction & gridfunction)
56{
57 mfem::ParFiniteElementSpace & fespace = *gridfunction.ParFESpace();
58 const int nelem = fespace.GetParMesh()->GetNE();
59 const int gf_ncomp = gridfunction.VectorDim();
60
61 fespace.GetParMesh()->EnsureNodes();
62
63 // Check FESpaces can be transferred
64 const auto map = fespace.FEColl()->GetMapType(fespace.GetParMesh()->Dimension());
65 const bool H1L2 = map == mfem::FiniteElement::VALUE || map == mfem::FiniteElement::INTEGRAL;
66 const bool RTND = map == mfem::FiniteElement::H_DIV || map == mfem::FiniteElement::H_CURL;
67 if (!H1L2 && !RTND)
68 mooseError("FESpace type not supported yet in transfers.");
69
70 // Project the interpolated values to the target FiniteElementSpace.
71 mfem::Ordering::Type dof_ordering = H1L2 ? mfem::Ordering::byNODES : mfem::Ordering::byVDIM;
72 mfem::Array<int> vdofs;
73 mfem::Vector vals;
74 int nodal_offset = 0;
75 for (const auto el : make_range(nelem))
76 {
77 const int nqpt = fespace.GetFE(el)->GetNodes().GetNPoints();
78 mfem::Vector dof_vals(nqpt * gf_ncomp);
79 nodal_vals.HostRead();
80 fespace.GetElementVDofs(el, vdofs); // Returned vdofs always indexed with ordering byNODES
81 for (const auto qp : make_range(nqpt))
82 for (const auto d : make_range(gf_ncomp))
83 dof_vals(Moose::MFEM::MFEMIndex(d, qp, gf_ncomp, nqpt, dof_ordering)) = nodal_vals(
84 Moose::MFEM::MFEMIndex(d, qp, gf_ncomp, nqpt, nodal_val_ordering) + nodal_offset);
85
86 if (H1L2)
87 gridfunction.SetSubVector(vdofs, dof_vals);
88 else if (RTND)
89 {
90 vals.SetSize(vdofs.Size());
91 fespace.GetFE(el)->ProjectFromNodes(dof_vals, *fespace.GetElementTransformation(el), vals);
92 gridfunction.SetSubVector(vdofs, vals);
93 }
94
95 nodal_offset += nqpt * gf_ncomp;
96 }
97 gridfunction.SetTrueVector();
98}
99
100#endif
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
unsigned int dim
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::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.