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 "MFEMValueSamplerBase.h" 13 : #include "MFEMProblem.h" 14 : #include "MFEMVectorUtils.h" 15 : 16 : #include "mfem/fem/fespace.hpp" 17 : 18 : namespace 19 : { 20 : void 21 598 : MFEMVectorToPostprocessorPoints( 22 : const mfem::Vector & mfem_points, 23 : std::vector<std::reference_wrapper<VectorPostprocessorValue>> & points, 24 : const unsigned int num_dims, 25 : const mfem::Ordering::Type ordering) 26 : { 27 598 : const unsigned int num_points = mfem_points.Size() / num_dims; 28 4236 : for (unsigned int i_point = 0; i_point < num_points; i_point++) 29 : { 30 11360 : for (unsigned int i_dim = 0; i_dim < num_dims; i_dim++) 31 : { 32 7722 : const size_t idx = Moose::MFEM::MFEMIndex(i_dim, i_point, num_dims, num_points, ordering); 33 : 34 7722 : points[i_dim].get()[i_point] = mfem_points(idx); 35 : } 36 : } 37 598 : } 38 : } 39 : 40 : InputParameters 41 4756 : MFEMValueSamplerBase::validParams() 42 : { 43 4756 : InputParameters params = MFEMVectorPostprocessor::validParams(); 44 : 45 19024 : MFEMExecutedObject::addRequiredDependencyParam<VariableName>( 46 : params, "variable", "The names of the variables that this VectorPostprocessor operates on"); 47 19024 : MooseEnum ordering("NODES VDIM", "VDIM", false); 48 14268 : params.addParam<MooseEnum>( 49 : "point_ordering", ordering, "Ordering style to use for point vector DoFs."); 50 : 51 9512 : return params; 52 4756 : } 53 : 54 280 : MFEMValueSamplerBase::MFEMValueSamplerBase(const InputParameters & parameters, 55 280 : const std::vector<Point> & points) 56 : : MFEMVectorPostprocessor(parameters), 57 280 : _var_name(getParam<VariableName>("variable")), 58 280 : _var(*getMFEMProblem().getGridFunction(_var_name)), 59 280 : _mesh(const_cast<mfem::ParMesh &>(getMFEMProblem().getMFEMVariableMesh(_var_name))), 60 280 : _finder(this->comm().get()), 61 560 : _points_ordering(getParam<MooseEnum>("point_ordering") == "NODES" ? mfem::Ordering::byNODES 62 : : mfem::Ordering::byVDIM), 63 280 : _points( 64 280 : Moose::MFEM::libMeshPointsToMFEMVector(points, _mesh.SpaceDimension(), _points_ordering)), 65 560 : _interp_vals(points.size()) 66 : { 67 280 : if (getMFEMProblem().mesh().shouldDisplace()) 68 0 : mooseError("MFEMValueSamplerBase does not yet support problems with displacement."); 69 : 70 : // set up points vector 71 280 : _mesh.EnsureNodes(); 72 280 : _finder.Setup(_mesh); 73 280 : _finder.FindPoints(_points, _points_ordering); 74 : 75 : // check all points were found 76 280 : mfem::Array<unsigned int> point_codes = _finder.GetCode(); 77 3552 : for (size_t i = 0; i < points.size(); i++) 78 : { 79 3272 : if (point_codes[i] > 1) 80 : { 81 0 : mooseError("MFEMValueSamplerBase could not find point at ", points[i], "."); 82 : } 83 : } 84 : 85 : // declare points vectors for outputting 86 280 : const auto mesh_dim = _mesh.SpaceDimension(); 87 904 : for (int i = 0; i < mesh_dim; i++) 88 : { 89 : std::reference_wrapper<VectorPostprocessorValue> declared_dim = 90 624 : this->declareVector("x_" + std::to_string(i)); 91 624 : declared_dim.get().resize(points.size()); 92 624 : _declared_points.push_back(declared_dim); 93 : } 94 : 95 : // declare value vectors for outputting 96 280 : const auto val_dim = _var.VectorDim(); 97 624 : for (int i = 0; i < val_dim; i++) 98 : { 99 : std::reference_wrapper<VectorPostprocessorValue> declared_dim = 100 344 : this->declareVector(_var_name + "_" + std::to_string(i)); 101 344 : declared_dim.get().resize(points.size()); 102 344 : _declared_vals.push_back(declared_dim); 103 : } 104 280 : } 105 : 106 : void 107 598 : MFEMValueSamplerBase::execute() 108 : { 109 598 : _finder.Interpolate(_var, _interp_vals); 110 598 : } 111 : 112 : void 113 598 : MFEMValueSamplerBase::finalize() 114 : { 115 598 : _interp_vals.HostReadWrite(); 116 598 : _points.HostReadWrite(); 117 : 118 598 : const auto mesh_dim = _mesh.SpaceDimension(); 119 598 : MFEMVectorToPostprocessorPoints(_points, _declared_points, mesh_dim, _points_ordering); 120 598 : const auto val_dims = _var.VectorDim(); 121 598 : const auto num_points = _declared_points[0].get().size(); 122 598 : const auto val_fespace_ordering = _var.FESpace()->GetOrdering(); 123 1260 : for (int i_dim = 0; i_dim < val_dims; i_dim++) 124 : { 125 4758 : for (size_t i_point = 0; i_point < num_points; i_point++) 126 : { 127 : const auto mfem_idx = 128 4096 : Moose::MFEM::MFEMIndex(i_dim, i_point, val_dims, num_points, val_fespace_ordering); 129 4096 : _declared_vals[i_dim].get()[i_point] = _interp_vals[mfem_idx]; 130 : } 131 : } 132 598 : } 133 : 134 : #endif // MOOSE_MFEM_ENABLED