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 : #pragma once 11 : 12 : #include "MooseTypes.h" 13 : #include "MooseVariableField.h" 14 : #include "SubProblem.h" 15 : #include "MooseMesh.h" 16 : #include "MooseVariableDataLinearFV.h" 17 : 18 : #include "libmesh/numeric_vector.h" 19 : #include "libmesh/dof_map.h" 20 : #include "libmesh/elem.h" 21 : #include "libmesh/quadrature.h" 22 : #include "libmesh/dense_vector.h" 23 : #include "libmesh/enum_fe_family.h" 24 : 25 : template <typename> 26 : class MooseLinearVariableFV; 27 : 28 : typedef MooseLinearVariableFV<Real> MooseLinearVariableFVReal; 29 : class FVDirichletBCBase; 30 : class FVFluxBC; 31 : class LinearFVBoundaryCondition; 32 : 33 : namespace libMesh 34 : { 35 : template <typename> 36 : class NumericVector; 37 : } 38 : 39 : /// This class provides variable solution interface for linear 40 : /// finite volume problems. 41 : /// This class is designed to store gradient information when enabled. 42 : template <typename OutputType> 43 : class MooseLinearVariableFV : public MooseVariableField<OutputType> 44 : { 45 : public: 46 : using OutputGradient = typename MooseVariableField<OutputType>::OutputGradient; 47 : using OutputSecond = typename MooseVariableField<OutputType>::OutputSecond; 48 : using OutputDivergence = typename MooseVariableField<OutputType>::OutputDivergence; 49 : 50 : using FieldVariableValue = typename MooseVariableField<OutputType>::FieldVariableValue; 51 : using FieldVariableGradient = typename MooseVariableField<OutputType>::FieldVariableGradient; 52 : using FieldVariableSecond = typename MooseVariableField<OutputType>::FieldVariableSecond; 53 : using FieldVariableCurl = typename MooseVariableField<OutputType>::FieldVariableCurl; 54 : using FieldVariableDivergence = typename MooseVariableField<OutputType>::FieldVariableDivergence; 55 : 56 : using OutputShape = typename MooseVariableField<OutputType>::OutputShape; 57 : using OutputShapeGradient = typename MooseVariableField<OutputType>::OutputShapeGradient; 58 : using OutputShapeSecond = typename MooseVariableField<OutputType>::OutputShapeSecond; 59 : using OutputShapeDivergence = typename MooseVariableField<OutputType>::OutputShapeDivergence; 60 : 61 : using OutputData = typename MooseVariableField<OutputType>::OutputData; 62 : using DoFValue = typename MooseVariableField<OutputType>::DoFValue; 63 : 64 : using FieldVariablePhiValue = typename MooseVariableField<OutputType>::FieldVariablePhiValue; 65 : using FieldVariablePhiGradient = 66 : typename MooseVariableField<OutputType>::FieldVariablePhiGradient; 67 : using FieldVariablePhiSecond = typename MooseVariableField<OutputType>::FieldVariablePhiSecond; 68 : using FieldVariablePhiDivergence = 69 : typename MooseVariableField<OutputType>::FieldVariablePhiDivergence; 70 : using ElemQpArg = Moose::ElemQpArg; 71 : using ElemSideQpArg = Moose::ElemSideQpArg; 72 : using ElemArg = Moose::ElemArg; 73 : using FaceArg = Moose::FaceArg; 74 : using StateArg = Moose::StateArg; 75 : using NodeArg = Moose::NodeArg; 76 : using ElemPointArg = Moose::ElemPointArg; 77 : using typename MooseVariableField<OutputType>::ValueType; 78 : using typename MooseVariableField<OutputType>::DotType; 79 : using typename MooseVariableField<OutputType>::GradientType; 80 : 81 : static InputParameters validParams(); 82 : MooseLinearVariableFV(const InputParameters & parameters); 83 : 84 645318 : virtual bool isFV() const override { return true; } 85 : 86 : /** 87 : * If the variable has a dirichlet boundary condition at face described by \p fi . 88 : */ 89 : virtual bool isDirichletBoundaryFace(const FaceInfo & fi) const; 90 : 91 : /** 92 : * Switch to request cell gradient computations. 93 : */ 94 1315 : void computeCellGradients() { _needs_cell_gradients = true; } 95 : 96 : /** 97 : * Check if cell gradient computations were requested for this variable. 98 : */ 99 24331 : virtual bool needsGradientVectorStorage() const override { return _needs_cell_gradients; } 100 : 101 : virtual bool isExtrapolatedBoundaryFace(const FaceInfo & fi, 102 : const Elem * elem, 103 : const Moose::StateArg & state) const override; 104 : 105 : /** 106 : * Get the variable gradient at a cell center. 107 : * @param elem_info The ElemInfo of the cell where we need the gradient 108 : */ 109 : const VectorValue<Real> gradSln(const ElemInfo & elem_info) const; 110 : 111 : /** 112 : * Compute interpolated gradient on the provided face. 113 : * @param face The face for which to retrieve the gradient. 114 : * @param state State argument which describes at what time / solution iteration state we want to 115 : * evaluate the variable 116 : */ 117 : VectorValue<Real> gradSln(const FaceInfo & fi, const StateArg & state) const; 118 : 119 : virtual void initialSetup() override; 120 : 121 : /** 122 : * Get the solution value for the provided element and seed the derivative for the corresponding 123 : * dof index 124 : * @param elem_info The element to retrieve the solution value for 125 : * @param state State argument which describes at what time / solution iteration state we want to 126 : * evaluate the variable 127 : */ 128 : Real getElemValue(const ElemInfo & elem_info, const StateArg & state) const; 129 : 130 : /** 131 : * Get the boundary condition object which corresponds to the given boundary ID 132 : * @param bd_id The boundary ID whose condition should be fetched 133 : */ 134 : LinearFVBoundaryCondition * getBoundaryCondition(const BoundaryID bd_id) const; 135 : 136 1627 : const std::unordered_map<BoundaryID, LinearFVBoundaryCondition *> & getBoundaryConditionMap() 137 : { 138 1627 : return _boundary_id_to_bc; 139 : } 140 : 141 267988 : virtual void prepareIC() override {} 142 : 143 2191 : virtual bool isNodal() const override final { return false; } 144 : 145 0 : virtual bool hasDoFsOnNodes() const override final { return false; } 146 : 147 18 : virtual bool isNodalDefined() const override final { return false; } 148 : 149 0 : virtual bool supportsFaceArg() const override final { return true; } 150 0 : virtual bool supportsElemSideQpArg() const override final { return false; } 151 : 152 : virtual const Elem * const & currentElem() const override; 153 : 154 0 : virtual bool computingSecond() const override final { return false; } 155 0 : virtual bool computingCurl() const override final { return false; } 156 0 : virtual bool computingDiv() const override final { return false; } 157 0 : virtual bool usesSecondPhiNeighbor() const override final { return false; } 158 : 159 : virtual void sizeMatrixTagData() override; 160 : 161 : protected: 162 : /// Throw an error when somebody requests time-related data from this variable 163 : [[noreturn]] void timeIntegratorError() const; 164 : 165 : /// Throw and error when somebody requests lower-dimensional data from this variable 166 : [[noreturn]] void lowerDError() const; 167 : 168 : /// Throw an error when somebody wants to use this variable as a nodal variable 169 : [[noreturn]] void nodalError() const; 170 : 171 : /// Throw an error when somebody wants to use this variable with automatic differentiation 172 : [[noreturn]] void adError() const; 173 : 174 : /** 175 : * Setup the boundary to Dirichlet BC map 176 : */ 177 : void cacheBoundaryBCMap(); 178 : 179 : usingMooseVariableBaseMembers; 180 : 181 : /// Boolean to check if this variable needs gradient computations. 182 : bool _needs_cell_gradients; 183 : 184 : /// Temporary storage for the cell gradient to avoid unnecessary allocations. 185 : mutable RealVectorValue _cell_gradient; 186 : 187 : /// Pointer to the cell gradients which are stored on the linear system 188 : const std::vector<std::unique_ptr<libMesh::NumericVector<libMesh::Number>>> & _grad_container; 189 : 190 : /// Holder for all the data associated with the "main" element. The data in this is 191 : /// mainly used by finite element-based loops such as the postprocessor and auxkernel 192 : /// loops 193 : std::unique_ptr<MooseVariableDataLinearFV<OutputType>> _element_data; 194 : 195 : /// Holder for all the data associated with the "neighbor" element. The data in this is 196 : /// mainly used by finite element-based loops such as the postprocessor and auxkernel 197 : /// loops 198 : std::unique_ptr<MooseVariableDataLinearFV<OutputType>> _neighbor_data; 199 : 200 : /// Map for easily accessing the boundary conditions based on the boundary IDs. 201 : /// We assume that each boundary has one boundary condition only. 202 : std::unordered_map<BoundaryID, LinearFVBoundaryCondition *> _boundary_id_to_bc; 203 : 204 : /// Cache the number of the system this variable belongs to 205 : const unsigned int _sys_num; 206 : 207 : friend void Moose::initDofIndices<>(MooseLinearVariableFV<OutputType> &, const Elem &); 208 : 209 : private: 210 : using MooseVariableField<OutputType>::evaluate; 211 : using MooseVariableField<OutputType>::evaluateGradient; 212 : using MooseVariableField<OutputType>::evaluateDot; 213 : 214 : virtual ValueType evaluate(const ElemArg & elem, const StateArg &) const override final; 215 : virtual ValueType evaluate(const FaceArg & face, const StateArg &) const override final; 216 : virtual ValueType evaluate(const NodeArg & node, const StateArg &) const override final; 217 : virtual ValueType evaluate(const ElemPointArg & elem_point, 218 : const StateArg & state) const override final; 219 : virtual ValueType evaluate(const ElemQpArg & elem_qp, 220 : const StateArg & state) const override final; 221 : virtual ValueType evaluate(const ElemSideQpArg & elem_side_qp, 222 : const StateArg & state) const override final; 223 : virtual GradientType evaluateGradient(const ElemQpArg & qp_arg, 224 : const StateArg &) const override final; 225 : virtual GradientType evaluateGradient(const ElemArg & elem_arg, 226 : const StateArg &) const override final; 227 : virtual GradientType evaluateGradient(const FaceArg & face, 228 : const StateArg &) const override final; 229 : virtual DotType evaluateDot(const ElemArg & elem, const StateArg &) const override final; 230 : 231 : /// The current (ghosted) solution. Note that this needs to be stored as a reference to a pointer 232 : /// because the solution might not exist at the time that this variable is constructed, so we 233 : /// cannot safely dereference at that time 234 : const libMesh::NumericVector<libMesh::Number> * const & _solution; 235 : 236 : /// Shape functions, only used when we are postprocessing or using this variable 237 : /// in an auxiliary system 238 : const FieldVariablePhiValue & _phi; 239 : const FieldVariablePhiGradient & _grad_phi; 240 : const FieldVariablePhiValue & _phi_face; 241 : const FieldVariablePhiGradient & _grad_phi_face; 242 : const FieldVariablePhiValue & _phi_face_neighbor; 243 : const FieldVariablePhiGradient & _grad_phi_face_neighbor; 244 : const FieldVariablePhiValue & _phi_neighbor; 245 : const FieldVariablePhiGradient & _grad_phi_neighbor; 246 : 247 : public: 248 : // ********************************************************************************* 249 : // ********************************************************************************* 250 : // The following functions are separated here because they are not essential for the 251 : // solver but are necessary to interface with the auxiliary and postprocessor 252 : // systems. 253 : // ********************************************************************************* 254 : // ********************************************************************************* 255 : 256 : virtual void setDofValue(const OutputData & /*value*/, unsigned int /*index*/) override; 257 : 258 : virtual void getDofIndices(const Elem * elem, 259 : std::vector<dof_id_type> & dof_indices) const override; 260 : 261 : virtual void setDofValues(const DenseVector<OutputData> & values) override; 262 : 263 : virtual void clearDofIndices() override; 264 : 265 558 : virtual unsigned int numberOfDofs() const override final { return 1; } 266 0 : virtual unsigned int numberOfDofsNeighbor() override final { return 1; } 267 : 268 : virtual unsigned int oldestSolutionStateRequested() const override final; 269 : 270 : virtual void clearAllDofIndices() override final; 271 : 272 : [[noreturn]] virtual const std::vector<dof_id_type> & dofIndicesLower() const override final; 273 : [[noreturn]] virtual const FieldVariablePhiValue & phiLower() const override; 274 : 275 : // Overriding these to make sure nothing happens during residual/jacobian setup. 276 : // The only time this can actually happen is when residual setup is called on the auxiliary 277 : // system. 278 24 : virtual void residualSetup() override {} 279 336 : virtual void jacobianSetup() override {} 280 : 281 0 : virtual libMesh::FEContinuity getContinuity() const override 282 : { 283 0 : return _element_data->getContinuity(); 284 : }; 285 : 286 : virtual void setNodalValue(const OutputType & value, unsigned int idx = 0) override; 287 : 288 : [[noreturn]] virtual const DoFValue & nodalVectorTagValue(TagID) const override; 289 : 290 : virtual const std::vector<dof_id_type> & dofIndices() const final; 291 : virtual const std::vector<dof_id_type> & dofIndicesNeighbor() const final; 292 : 293 668178 : virtual void prepare() override final {} 294 0 : virtual void prepareNeighbor() override final {} 295 0 : virtual void prepareAux() override final {} 296 18 : virtual void reinitNode() override final {} 297 0 : virtual void reinitNodes(const std::vector<dof_id_type> & /*nodes*/) override final {} 298 0 : virtual void reinitNodesNeighbor(const std::vector<dof_id_type> & /*nodes*/) override final {} 299 1868 : virtual void reinitAux() override final {} 300 0 : virtual void reinitAuxNeighbor() override final {} 301 0 : virtual void prepareLowerD() override final {} 302 : 303 : virtual void computeElemValuesFace() override; 304 : virtual void computeNeighborValuesFace() override; 305 : virtual void computeNeighborValues() override; 306 : virtual void computeLowerDValues() override final; 307 : 308 : virtual void computeNodalNeighborValues() override final; 309 : virtual void computeNodalValues() override final; 310 : 311 : virtual void computeElemValues() override; 312 0 : virtual void computeFaceValues(const FaceInfo & /*fi*/) override {} 313 : 314 : virtual void setLowerDofValues(const DenseVector<OutputData> & values) override; 315 : 316 : virtual void insert(libMesh::NumericVector<libMesh::Number> & vector) override; 317 : virtual void insertLower(libMesh::NumericVector<libMesh::Number> & vector) override; 318 : virtual void add(libMesh::NumericVector<libMesh::Number> & vector) override; 319 : 320 : virtual void setActiveTags(const std::set<TagID> & vtags) override; 321 : 322 : [[noreturn]] virtual const MooseArray<OutputType> & nodalValueArray() const override; 323 : [[noreturn]] virtual const MooseArray<OutputType> & nodalValueOldArray() const override; 324 : [[noreturn]] virtual const MooseArray<OutputType> & nodalValueOlderArray() const override; 325 : 326 221 : virtual const FieldVariablePhiValue & phi() const override final { return _phi; } 327 0 : virtual const FieldVariablePhiGradient & gradPhi() const override final { return _grad_phi; } 328 : [[noreturn]] virtual const FieldVariablePhiSecond & secondPhi() const override final; 329 : [[noreturn]] const FieldVariablePhiValue & curlPhi() const override final; 330 : [[noreturn]] const FieldVariablePhiDivergence & divPhi() const override final; 331 : 332 0 : virtual const FieldVariablePhiValue & phiFace() const override final { return _phi_face; } 333 0 : virtual const FieldVariablePhiGradient & gradPhiFace() const override final 334 : { 335 0 : return _grad_phi_face; 336 : } 337 : [[noreturn]] virtual const FieldVariablePhiSecond & secondPhiFace() const override final; 338 : 339 0 : virtual const FieldVariablePhiValue & phiFaceNeighbor() const override final 340 : { 341 0 : return _phi_face_neighbor; 342 : } 343 0 : virtual const FieldVariablePhiGradient & gradPhiFaceNeighbor() const override final 344 : { 345 0 : return _grad_phi_face_neighbor; 346 : } 347 : [[noreturn]] virtual const FieldVariablePhiSecond & secondPhiFaceNeighbor() const override final; 348 : 349 0 : virtual const FieldVariablePhiValue & phiNeighbor() const override final { return _phi_neighbor; } 350 0 : virtual const FieldVariablePhiGradient & gradPhiNeighbor() const override final 351 : { 352 0 : return _grad_phi_neighbor; 353 : } 354 : [[noreturn]] virtual const FieldVariablePhiSecond & secondPhiNeighbor() const override final; 355 : 356 : virtual const FieldVariableValue & vectorTagValue(TagID tag) const override; 357 : virtual const DoFValue & vectorTagDofValue(TagID tag) const override; 358 : [[noreturn]] virtual const DoFValue & nodalMatrixTagValue(TagID tag) const override; 359 : virtual const FieldVariableValue & matrixTagValue(TagID tag) const override; 360 : 361 : virtual const FieldVariableValue & sln() const override; 362 : virtual const FieldVariableValue & slnOld() const override; 363 : virtual const FieldVariableValue & slnOlder() const override; 364 : virtual const FieldVariableGradient & gradSln() const override; 365 : virtual const FieldVariableGradient & gradSlnOld() const override; 366 : virtual const FieldVariableValue & slnNeighbor() const override; 367 : virtual const FieldVariableValue & slnOldNeighbor() const override; 368 : virtual const FieldVariableGradient & gradSlnNeighbor() const override; 369 : virtual const FieldVariableGradient & gradSlnOldNeighbor() const override; 370 : 371 : [[noreturn]] virtual const ADTemplateVariableSecond<OutputType> & adSecondSln() const override; 372 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & adUDot() const override; 373 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & adUDotDot() const override; 374 : [[noreturn]] virtual const ADTemplateVariableGradient<OutputType> & adGradSlnDot() const override; 375 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & adSlnNeighbor() const override; 376 : [[noreturn]] virtual const ADTemplateVariableGradient<OutputType> & 377 : adGradSlnNeighbor() const override; 378 : [[noreturn]] virtual const ADTemplateVariableSecond<OutputType> & 379 : adSecondSlnNeighbor() const override; 380 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & adUDotNeighbor() const override; 381 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & 382 : adUDotDotNeighbor() const override; 383 : [[noreturn]] virtual const ADTemplateVariableGradient<OutputType> & 384 : adGradSlnNeighborDot() const override; 385 : [[noreturn]] virtual const ADTemplateVariableValue<OutputType> & adSln() const override; 386 : [[noreturn]] virtual const ADTemplateVariableGradient<OutputType> & adGradSln() const override; 387 : [[noreturn]] virtual const ADTemplateVariableCurl<OutputType> & adCurlSln() const override; 388 : [[noreturn]] virtual const ADTemplateVariableCurl<OutputType> & 389 : adCurlSlnNeighbor() const override; 390 : 391 : virtual const DoFValue & dofValues() const override; 392 : virtual const DoFValue & dofValuesOld() const override; 393 : 394 : virtual const DoFValue & dofValuesOlder() const override; 395 : virtual const DoFValue & dofValuesPreviousNL() const override; 396 : virtual const DoFValue & dofValuesNeighbor() const override; 397 : virtual const DoFValue & dofValuesOldNeighbor() const override; 398 : virtual const DoFValue & dofValuesOlderNeighbor() const override; 399 : virtual const DoFValue & dofValuesPreviousNLNeighbor() const override; 400 : [[noreturn]] virtual const DoFValue & dofValuesDot() const override; 401 : [[noreturn]] virtual const DoFValue & dofValuesDotNeighbor() const override; 402 : [[noreturn]] virtual const DoFValue & dofValuesDotOld() const override; 403 : [[noreturn]] virtual const DoFValue & dofValuesDotOldNeighbor() const override; 404 : [[noreturn]] virtual const DoFValue & dofValuesDotDot() const override; 405 : [[noreturn]] virtual const DoFValue & dofValuesDotDotNeighbor() const override; 406 : [[noreturn]] virtual const DoFValue & dofValuesDotDotOld() const override; 407 : [[noreturn]] virtual const DoFValue & dofValuesDotDotOldNeighbor() const override; 408 : [[noreturn]] virtual const MooseArray<libMesh::Number> & dofValuesDuDotDu() const override; 409 : [[noreturn]] virtual const MooseArray<libMesh::Number> & 410 : dofValuesDuDotDuNeighbor() const override; 411 : [[noreturn]] virtual const MooseArray<libMesh::Number> & dofValuesDuDotDotDu() const override; 412 : [[noreturn]] virtual const MooseArray<libMesh::Number> & 413 : dofValuesDuDotDotDuNeighbor() const override; 414 : 415 : [[noreturn]] virtual const MooseArray<ADReal> & adDofValues() const override; 416 : [[noreturn]] virtual const MooseArray<ADReal> & adDofValuesNeighbor() const override; 417 : [[noreturn]] virtual const MooseArray<ADReal> & adDofValuesDot() const override; 418 : [[noreturn]] virtual const dof_id_type & nodalDofIndex() const override final; 419 : [[noreturn]] virtual const dof_id_type & nodalDofIndexNeighbor() const override final; 420 : 421 0 : virtual std::size_t phiSize() const override final { return _phi.size(); } 422 0 : virtual std::size_t phiFaceSize() const override final { return _phi_face.size(); } 423 0 : virtual std::size_t phiNeighborSize() const override final { return _phi_neighbor.size(); } 424 0 : virtual std::size_t phiFaceNeighborSize() const override final 425 : { 426 0 : return _phi_face_neighbor.size(); 427 : } 428 : [[noreturn]] virtual std::size_t phiLowerSize() const override final; 429 : }; 430 : 431 : template <typename OutputType> 432 : typename MooseLinearVariableFV<OutputType>::ValueType 433 35624 : MooseLinearVariableFV<OutputType>::evaluate(const ElemArg & elem_arg, const StateArg & state) const 434 : { 435 35624 : const auto & elem_info = this->_mesh.elemInfo(elem_arg.elem->id()); 436 35624 : return getElemValue(elem_info, state); 437 : } 438 : 439 : template <typename OutputType> 440 : typename MooseLinearVariableFV<OutputType>::ValueType 441 0 : MooseLinearVariableFV<OutputType>::evaluate(const ElemPointArg & elem_point, 442 : const StateArg & state) const 443 : { 444 0 : const auto & elem_info = this->_mesh.elemInfo(elem_point.elem->id()); 445 0 : return getElemValue(elem_info, state); 446 : } 447 : 448 : template <typename OutputType> 449 : typename MooseLinearVariableFV<OutputType>::ValueType 450 264772 : MooseLinearVariableFV<OutputType>::evaluate(const ElemQpArg & elem_qp, const StateArg & state) const 451 : { 452 264772 : const auto & elem_info = this->_mesh.elemInfo(elem_qp.elem->id()); 453 264772 : return getElemValue(elem_info, state); 454 : } 455 : 456 : template <typename OutputType> 457 : typename MooseLinearVariableFV<OutputType>::ValueType 458 0 : MooseLinearVariableFV<OutputType>::evaluate(const ElemSideQpArg & elem_side_qp, 459 : const StateArg & state) const 460 : { 461 0 : return (*this)(ElemPointArg{elem_side_qp.elem, elem_side_qp.point, false}, state); 462 : } 463 : 464 : template <typename OutputType> 465 : typename MooseLinearVariableFV<OutputType>::GradientType 466 1800 : MooseLinearVariableFV<OutputType>::evaluateGradient(const ElemQpArg & qp_arg, 467 : const StateArg & /*state*/) const 468 : { 469 1800 : const auto & elem_info = this->_mesh.elemInfo(qp_arg.elem->id()); 470 1800 : return gradSln(elem_info); 471 : } 472 : 473 : template <typename OutputType> 474 : typename MooseLinearVariableFV<OutputType>::GradientType 475 0 : MooseLinearVariableFV<OutputType>::evaluateGradient(const ElemArg & elem_arg, 476 : const StateArg & /*state*/) const 477 : { 478 0 : const auto & elem_info = this->_mesh.elemInfo(elem_arg.elem->id()); 479 0 : return gradSln(elem_info); 480 : } 481 : 482 : template <typename OutputType> 483 : typename MooseLinearVariableFV<OutputType>::GradientType 484 180 : MooseLinearVariableFV<OutputType>::evaluateGradient(const FaceArg & face, 485 : const StateArg & state) const 486 : { 487 : mooseAssert(face.fi, "We must have a non-null face information"); 488 180 : return gradSln(*face.fi, state); 489 : } 490 : 491 : template <typename OutputType> 492 : void 493 0 : MooseLinearVariableFV<OutputType>::timeIntegratorError() const 494 : { 495 0 : mooseError("MooseLinearVariableFV does not support time integration at the moment! The variable " 496 : "which is causing the issue: ", 497 0 : this->name()); 498 : } 499 : 500 : template <typename OutputType> 501 : void 502 0 : MooseLinearVariableFV<OutputType>::lowerDError() const 503 : { 504 0 : mooseError("Lower dimensional element support not implemented for finite volume variables!The " 505 : "variable which is causing the issue: ", 506 0 : this->name()); 507 : } 508 : 509 : template <typename OutputType> 510 : void 511 0 : MooseLinearVariableFV<OutputType>::nodalError() const 512 : { 513 0 : mooseError("FV variables don't support nodal variable treatment! The variable which is causing " 514 : "the issue: ", 515 0 : this->name()); 516 : } 517 : 518 : template <typename OutputType> 519 : void 520 0 : MooseLinearVariableFV<OutputType>::adError() const 521 : { 522 0 : mooseError("Linear FV variable does not support automatic differentiation, the variable which is " 523 : "attempting it is: ", 524 0 : this->name()); 525 : } 526 : 527 : // Declare all the specializations, as the template specialization declarations below must know 528 : template <> 529 : ADReal MooseLinearVariableFV<Real>::evaluateDot(const ElemArg & elem, const StateArg & state) const; 530 : 531 : // Prevent implicit instantiation in other translation units where these classes are used 532 : extern template class MooseLinearVariableFV<Real>;