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 "MFEMVariable.h" 13 : #include "MFEMProblem.h" 14 : #include "MFEMFESpace.h" 15 : #include "MFEMFESpaceHierarchy.h" 16 : #include "MooseVariableBase.h" 17 : #include "MFEMVectorMagnitudeCoefficient.h" 18 : 19 : registerMooseObject("MooseApp", MFEMVariable); 20 : 21 : InputParameters 22 9415 : MFEMVariable::validParams() 23 : { 24 9415 : InputParameters params = MFEMObject::validParams(); 25 : // Create user-facing 'boundary' input for restricting inheriting object to boundaries. 26 37660 : params.addParam<MFEMFESpaceName>("fespace", 27 : "The finite element space this variable is defined on."); 28 28245 : params.addParam<std::string>( 29 : "fespace_hierarchy", 30 : "Name of a FESpaceHierarchy; the variable lives on its finest level. " 31 : "Mutually exclusive with 'fespace'."); 32 : // Require moose variable parameters (not used!) 33 9415 : params += MooseVariableBase::validParams(); 34 18830 : params.addClassDescription( 35 : "Class for adding MFEM variables to the problem (`mfem::ParGridFunction`s)."); 36 18830 : params.registerBase("MooseVariableBase"); 37 18830 : params.registerSystemAttributeName("MooseVariableBase"); 38 28245 : params.addParam<VariableName>( 39 : "time_derivative", 40 : "Optional name to assign to the time derivative of the variable in transient problems."); 41 9415 : return params; 42 0 : } 43 : 44 3806 : MFEMVariable::MFEMVariable(const InputParameters & parameters) 45 : : MFEMObject(parameters), 46 3818 : _time_derivative_name( 47 11418 : isParamValid("time_derivative") 48 3806 : ? getParam<VariableName>("time_derivative") 49 : : VariableName( 50 3794 : getMFEMProblem().getProblemData().time_derivative_map.createTimeDerivativeName( 51 7600 : name()))) 52 : { 53 7612 : const bool has_fespace = isParamSetByUser("fespace"); 54 7612 : const bool has_hierarchy = isParamSetByUser("fespace_hierarchy"); 55 : 56 3806 : if (has_fespace && has_hierarchy) 57 0 : paramError("fespace_hierarchy", "Cannot specify both 'fespace' and 'fespace_hierarchy'."); 58 3806 : if (!has_fespace && !has_hierarchy) 59 0 : paramError("fespace", "Either 'fespace' or 'fespace_hierarchy' must be provided."); 60 : 61 3806 : if (has_fespace) 62 : { 63 7594 : const auto & fespace = getMFEMProblem().getMFEMObject<MFEMFESpace>( 64 11391 : "MFEMFESpace", getParam<MFEMFESpaceName>("fespace")); 65 3797 : _par_fespace = fespace.getFESpace(); 66 3797 : _is_scalar = fespace.isScalar(); 67 : } 68 : else 69 : { 70 18 : const auto & hierarchy_name = getParam<std::string>("fespace_hierarchy"); 71 18 : const auto & hierarchy = getMFEMProblem().getMFEMObject<MFEMFESpaceHierarchy>( 72 : "MFEMFESpaceHierarchy", hierarchy_name); 73 9 : _par_fespace = getMFEMProblem().getProblemData().fespaces.GetShared(hierarchy_name); 74 9 : _is_scalar = hierarchy.isScalar(); 75 : } 76 : 77 3806 : _gridfunction = buildGridFunction(); 78 3806 : *_gridfunction = 0.0; 79 3806 : } 80 : 81 : const std::shared_ptr<mfem::ParGridFunction> 82 3806 : MFEMVariable::buildGridFunction() 83 : { 84 3806 : return std::make_shared<mfem::ParGridFunction>(_par_fespace.get()); 85 : } 86 : 87 : void 88 3806 : MFEMVariable::declareCoefficients() 89 : { 90 3806 : const int cont_type = _par_fespace->FEColl()->GetContType(); 91 3806 : if (_is_scalar) 92 : { 93 4676 : getMFEMProblem().getCoefficients().declareScalar<mfem::GridFunctionCoefficient>( 94 4676 : name(), getGridFunction().get()); 95 : // If gradient is well-defined on this variable, create auxiliary coefficient 96 2338 : if (cont_type == mfem::FiniteElementCollection::CONTINUOUS) 97 : { 98 3496 : getMFEMProblem().getCoefficients().declareVector<mfem::GradientGridFunctionCoefficient>( 99 3496 : name() + "_grad", getGridFunction().get()); 100 5244 : getMFEMProblem().getCoefficients().declareScalar<MFEMVectorMagnitudeCoefficient>( 101 3496 : name() + "_grad_mag", 102 3496 : getMFEMProblem().getCoefficients().getVectorCoefficient(name() + "_grad")); 103 : } 104 : } 105 : else 106 : { 107 2936 : getMFEMProblem().getCoefficients().declareVector<mfem::VectorGridFunctionCoefficient>( 108 2936 : name(), getGridFunction().get()); 109 4404 : getMFEMProblem().getCoefficients().declareScalar<MFEMVectorMagnitudeCoefficient>( 110 4404 : name() + "_mag", getMFEMProblem().getCoefficients().getVectorCoefficient(name())); 111 : // If curl is well-defined on this variable, create auxiliary coefficient 112 1468 : if (cont_type == mfem::FiniteElementCollection::TANGENTIAL || 113 : cont_type == mfem::FiniteElementCollection::CONTINUOUS) 114 : { 115 2018 : getMFEMProblem().getCoefficients().declareVector<mfem::CurlGridFunctionCoefficient>( 116 2018 : name() + "_curl", getGridFunction().get()); 117 3027 : getMFEMProblem().getCoefficients().declareScalar<MFEMVectorMagnitudeCoefficient>( 118 2018 : name() + "_curl_mag", 119 2018 : getMFEMProblem().getCoefficients().getVectorCoefficient(name() + "_curl")); 120 : } 121 : // If divergence is well-defined on this variable, create auxiliary coefficient 122 1468 : if (cont_type == mfem::FiniteElementCollection::NORMAL || 123 : cont_type == mfem::FiniteElementCollection::CONTINUOUS) 124 942 : getMFEMProblem().getCoefficients().declareScalar<mfem::DivergenceGridFunctionCoefficient>( 125 942 : name() + "_div", getGridFunction().get()); 126 : } 127 3806 : } 128 : 129 : #endif