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 "MFEMNDtoRTAux.h" 13 : #include "MFEMProblem.h" 14 : 15 : registerMooseObject("MooseApp", MFEMNDtoRTAux); 16 : 17 : InputParameters 18 2122 : MFEMNDtoRTAux::validParams() 19 : { 20 2122 : InputParameters params = MFEMAuxKernel::validParams(); 21 4244 : params.addClassDescription( 22 : "Copies the DoFs of a 2D Nedelec H(curl) MFEM Variable " 23 : "into a Raviart-Thomas H(div) MFEM Variable. In 2D ONLY this represents a 90 degree rotation " 24 : "because the RT basis is the rotated ND basis."); 25 8488 : MFEMExecutedObject::addRequiredDependencyParam<VariableName>( 26 : params, "source", "Name of H(curl) conforming ND variable to copy."); 27 4244 : params.addParam<mfem::real_t>( 28 : "scale_factor", 29 4244 : 1.0, 30 : "Optional scale factor. Negative values can be used to flip the sign of the rotation."); 31 : 32 2122 : return params; 33 0 : } 34 : 35 12 : MFEMNDtoRTAux::MFEMNDtoRTAux(const InputParameters & parameters) 36 : : MFEMAuxKernel(parameters), 37 12 : _nd_source_var_name(getParam<VariableName>("source")), 38 12 : _nd_source_var(*getMFEMProblem().getGridFunction(_nd_source_var_name)), 39 36 : _scale_factor(getParam<mfem::real_t>("scale_factor")) 40 : { 41 12 : const mfem::ParFiniteElementSpace * source_fes = _nd_source_var.ParFESpace(); 42 12 : const mfem::ParFiniteElementSpace * target_fes = _result_var.ParFESpace(); 43 : 44 : mooseAssert(source_fes, "The source variable has no valid ParFiniteElementSpace."); 45 : mooseAssert(target_fes, "The target variable has no valid ParFiniteElementSpace."); 46 : 47 12 : const mfem::FiniteElementCollection * source_fec = source_fes->FEColl(); 48 12 : const mfem::FiniteElementCollection * target_fec = target_fes->FEColl(); 49 : 50 12 : if (!dynamic_cast<const mfem::ND_FECollection *>(source_fec)) 51 0 : paramError("source", 52 : "The source variable must use an MFEM H(curl) Nedelec space. " 53 : "Detected FE collection: ", 54 0 : source_fec->Name(), 55 : "."); 56 12 : if (!dynamic_cast<const mfem::RT_FECollection *>(target_fec)) 57 0 : mooseError("The target variable must use an MFEM H(div) Raviart-Thomas space. " 58 : "Detected FE collection: ", 59 0 : target_fec->Name(), 60 : "."); 61 : 62 12 : if (source_fes->GetMesh()->Dimension() != 2 || target_fes->GetMesh()->Dimension() != 2) 63 0 : mooseError("MFEMNDtoRTAux is only valid in 2D."); 64 : 65 12 : if (_nd_source_var.Size() != _result_var.Size()) 66 0 : paramError("source", 67 : "The source ND variable and target RT variable must have the same local DoF size. " 68 : "Source size = ", 69 0 : _nd_source_var.Size(), 70 : ", target size = ", 71 0 : _result_var.Size(), 72 : "."); 73 12 : } 74 : 75 : void 76 12 : MFEMNDtoRTAux::execute() 77 : { 78 12 : _result_var = _nd_source_var; 79 12 : _result_var *= _scale_factor; 80 12 : } 81 : 82 : #endif