LCOV - code coverage report
Current view: top level - src/mfem/utils - MFEMNodalProjector.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 52 53 98.1 %
Date: 2026-05-29 20:35:17 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14