LCOV - code coverage report
Current view: top level - src/mfem/vectorpostprocessors - MFEMPointScalarCoefficientValueSampler.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 329044 Lines: 50 55 90.9 %
Date: 2026-08-03 21:12:22 Functions: 6 6 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 "MFEMPointScalarCoefficientValueSampler.h"
      13             : 
      14             : #include "MFEMProblem.h"
      15             : #include "SubProblem.h"
      16             : 
      17             : registerMooseObject("MooseApp", MFEMPointScalarCoefficientValueSampler);
      18             : 
      19             : namespace
      20             : {
      21             : mfem::ParMesh &
      22          29 : mainMesh(const InputParameters & parameters)
      23             : {
      24             :   auto & problem =
      25          87 :       static_cast<MFEMProblem &>(*parameters.getCheckedPointerParam<SubProblem *>("_subproblem"));
      26          29 :   return problem.mesh().getMFEMParMesh();
      27             : }
      28             : }
      29             : 
      30             : InputParameters
      31        2188 : MFEMPointScalarCoefficientValueSampler::validParams()
      32             : {
      33        2188 :   InputParameters params = MFEMSamplerBase::validParams();
      34        4376 :   params.addClassDescription("Sample a real scalar MFEM coefficient at specific points.");
      35        8752 :   params.addRequiredParam<MFEMScalarCoefficientName>("coefficient",
      36             :                                                      "The scalar coefficient to sample.");
      37        6564 :   params.addRequiredParam<std::vector<Point>>("points",
      38             :                                               "The points where the coefficient is evaluated.");
      39        2188 :   return params;
      40           0 : }
      41             : 
      42          29 : MFEMPointScalarCoefficientValueSampler::MFEMPointScalarCoefficientValueSampler(
      43          29 :     const InputParameters & parameters)
      44          29 :   : MFEMSamplerBase(parameters, parameters.get<std::vector<Point>>("points"), mainMesh(parameters)),
      45          29 :     _coefficient(nullptr),
      46          29 :     _interp_vals(_query_points.size()),
      47          87 :     _declared_vals(declareVector(getParam<MFEMScalarCoefficientName>("coefficient")))
      48             : {
      49          29 :   _declared_vals.resize(_query_points.size());
      50          29 : }
      51             : 
      52             : void
      53          29 : MFEMPointScalarCoefficientValueSampler::initialSetup()
      54             : {
      55          58 :   _coefficient = &getScalarCoefficient("coefficient");
      56          29 :   if (dynamic_cast<mfem::QuadratureFunctionCoefficient *>(_coefficient))
      57           4 :     paramError("coefficient",
      58             :                "Quadrature-function-backed coefficients can only be evaluated at the quadrature "
      59             :                "points configured by their quadrature rule and cannot be sampled at arbitrary "
      60             :                "points.");
      61             : 
      62          27 :   MFEMSamplerBase::initialSetup();
      63             : 
      64          27 :   const auto & point_codes = _finder.GetCode();
      65          88 :   for (const auto i : index_range(_query_points))
      66          63 :     if (PointLocationCode(point_codes[i]) == PointLocationCode::BORDER)
      67           9 :       mooseWarning(typeAndName(),
      68             :                    " found point ",
      69           9 :                    _query_points[i],
      70             :                    " on an element boundary. An arbitrary coefficient may be discontinuous "
      71             :                    "there, so the element selected by GSLIB will supply the sampled value.");
      72          25 : }
      73             : 
      74             : void
      75          21 : MFEMPointScalarCoefficientValueSampler::execute()
      76             : {
      77          21 :   mfem::Array<unsigned int> received_elements;
      78          21 :   mfem::Array<unsigned int> received_codes;
      79          21 :   mfem::Vector received_reference_points;
      80          21 :   _finder.DistributePointInfoToOwningMPIRanks(
      81             :       received_elements, received_reference_points, received_codes);
      82             : 
      83          21 :   const auto mesh_dim = _mesh.Dimension();
      84          21 :   mfem::Vector evaluated_values(received_elements.Size());
      85          70 :   for (const auto i : make_range(received_elements.Size()))
      86             :   {
      87             :     mfem::IntegrationPoint integration_point;
      88          49 :     if (mesh_dim == 1)
      89           0 :       integration_point.Set1(received_reference_points[i]);
      90          49 :     else if (mesh_dim == 2)
      91          49 :       integration_point.Set2(received_reference_points[2 * i],
      92          49 :                              received_reference_points[2 * i + 1]);
      93             :     else
      94           0 :       integration_point.Set3(received_reference_points[3 * i],
      95           0 :                              received_reference_points[3 * i + 1],
      96           0 :                              received_reference_points[3 * i + 2]);
      97             : 
      98          49 :     auto & transformation = *_mesh.GetElementTransformation(received_elements[i]);
      99          49 :     transformation.SetIntPoint(&integration_point);
     100          49 :     evaluated_values[i] = _coefficient->Eval(transformation, integration_point);
     101             :   }
     102             : 
     103             :   // With one scalar value per point, byNODES and byVDIM orderings are identical.
     104          21 :   _finder.DistributeInterpolatedValues(evaluated_values, 1, mfem::Ordering::byVDIM, _interp_vals);
     105          21 : }
     106             : 
     107             : void
     108          21 : MFEMPointScalarCoefficientValueSampler::finalizeValues()
     109             : {
     110          21 :   const auto * const interp_vals = _interp_vals.HostRead();
     111          70 :   for (const auto i : index_range(_declared_vals))
     112          49 :     _declared_vals[i] = interp_vals[i];
     113          21 : }
     114             : 
     115             : #endif // MOOSE_MFEM_ENABLED

Generated by: LCOV version 1.14