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