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 : #include "SideAdvectiveFluxIntegral.h"
11 : #include "MathFVUtils.h"
12 :
13 : #include "metaphysicl/raw_type.h"
14 :
15 : registerMooseObject("MooseApp", SideAdvectiveFluxIntegral);
16 : registerMooseObject("MooseApp", ADSideAdvectiveFluxIntegral);
17 :
18 : template <bool is_ad>
19 : InputParameters
20 28760 : SideAdvectiveFluxIntegralTempl<is_ad>::validParams()
21 : {
22 28760 : InputParameters params = SideIntegralPostprocessor::validParams();
23 28760 : MooseEnum component("x y z normal");
24 :
25 28760 : params.addRequiredParam<MooseEnum>("component", component, "The desired component of flux.");
26 28760 : params.addRequiredParam<MooseFunctorName>("vel_x", "x-component of the velocity vector");
27 28760 : params.addParam<MooseFunctorName>("vel_y", "y-component of the velocity vector");
28 28760 : params.addParam<MooseFunctorName>("vel_z", "z-component of the velocity vector");
29 28760 : params.addCoupledVar(
30 : "advected_variable",
31 : "The advected variable quantity of which to compute advection flux; useful for "
32 : "finite element simulations");
33 86280 : params.addParam<MaterialPropertyName>(
34 : "advected_mat_prop",
35 57520 : 0,
36 : "The advected material property of which to compute advection flux; "
37 : "useful for finite element simulations");
38 28760 : params.addParam<MooseFunctorName>("advected_quantity",
39 : "The quantity to advect. This is the canonical parameter to "
40 : "set the advected quantity when finite volume is being used.");
41 :
42 28760 : params.addClassDescription("Computes the volumetric advected quantity through a sideset.");
43 :
44 57520 : return params;
45 28760 : }
46 :
47 : template <bool is_ad>
48 120 : SideAdvectiveFluxIntegralTempl<is_ad>::SideAdvectiveFluxIntegralTempl(
49 : const InputParameters & parameters)
50 : : SideIntegralPostprocessor(parameters),
51 120 : _use_normal(getParam<MooseEnum>("component") == "normal"),
52 120 : _component(getParam<MooseEnum>("component")),
53 120 : _advected_variable_supplied(isParamValid("advected_variable")),
54 120 : _advected_variable(_advected_variable_supplied ? coupledValue("advected_variable") : _zero),
55 120 : _advected_mat_prop_supplied(parameters.isParamSetByUser("advected_mat_prop")),
56 120 : _advected_material_property(getGenericMaterialProperty<Real, is_ad>("advected_mat_prop")),
57 120 : _adv_quant(isParamValid("advected_quantity") ? &getFunctor<Real>("advected_quantity")
58 : : nullptr),
59 120 : _vel_x(getFunctor<Real>("vel_x")),
60 120 : _vel_y(_mesh.dimension() >= 2 ? &getFunctor<Real>("vel_y") : nullptr),
61 240 : _vel_z(_mesh.dimension() == 3 ? &getFunctor<Real>("vel_z") : nullptr)
62 : {
63 : // Check that at most one advected quantity has been provided
64 120 : if (_advected_mat_prop_supplied)
65 : {
66 52 : if (_advected_variable_supplied || _adv_quant)
67 0 : mooseError(
68 : "SideAdvectiveFluxIntegralPostprocessor should be provided either an advected quantity "
69 : "or an advected material property");
70 : }
71 :
72 : // Check whether a finite element or finite volume variable is provide
73 120 : _qp_integration = !_adv_quant;
74 :
75 120 : checkFunctorSupportsSideIntegration<Real>("vel_x", _qp_integration);
76 120 : if (_vel_y)
77 120 : checkFunctorSupportsSideIntegration<Real>("vel_y", _qp_integration);
78 120 : if (_vel_z)
79 0 : checkFunctorSupportsSideIntegration<Real>("vel_z", _qp_integration);
80 120 : }
81 :
82 : template <bool is_ad>
83 : Real
84 64 : SideAdvectiveFluxIntegralTempl<is_ad>::computeFaceInfoIntegral(const FaceInfo * const fi)
85 : {
86 : mooseAssert(fi, "We should have a face info in " + name());
87 : mooseAssert(_adv_quant, "We should have an advected quantity in " + name());
88 :
89 64 : const auto state = determineState();
90 :
91 : // Get face value for velocity
92 64 : const auto vel_x =
93 64 : (_vel_x)(Moose::FaceArg(
94 : {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
95 : state);
96 64 : const auto vel_y =
97 64 : _vel_y
98 128 : ? ((*_vel_y)(
99 64 : Moose::FaceArg(
100 : {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
101 : state))
102 : : 0;
103 64 : const auto vel_z =
104 64 : _vel_z
105 64 : ? ((*_vel_z)(
106 0 : Moose::FaceArg(
107 : {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr}),
108 : state))
109 : : 0;
110 :
111 64 : auto fi_normal = _current_elem == fi->elemPtr() ? fi->normal() : Point(-fi->normal());
112 64 : const bool elem_is_upwind = RealVectorValue(vel_x, vel_y, vel_z) * fi_normal >= 0;
113 :
114 128 : const auto adv_quant_face = (*_adv_quant)(
115 64 : Moose::FaceArg(
116 : {fi, Moose::FV::LimiterType::CentralDifference, elem_is_upwind, false, nullptr, nullptr}),
117 : state);
118 :
119 64 : return fi_normal * adv_quant_face * RealVectorValue(vel_x, vel_y, vel_z);
120 : }
121 :
122 : template <bool is_ad>
123 : Real
124 387 : SideAdvectiveFluxIntegralTempl<is_ad>::computeQpIntegral()
125 : {
126 : using MetaPhysicL::raw_value;
127 :
128 387 : const auto state = determineState();
129 387 : const Moose::ElemSideQpArg side_arg = {_current_elem, _current_side, _qp, _qrule, _q_point[_qp]};
130 387 : const auto vel_x = raw_value(_vel_x(side_arg, state));
131 387 : const auto vel_y = _vel_y ? raw_value((*_vel_y)(side_arg, state)) : 0;
132 387 : const auto vel_z = _vel_z ? raw_value((*_vel_z)(side_arg, state)) : 0;
133 :
134 387 : if (_advected_variable_supplied)
135 : {
136 :
137 131 : auto & variable = getCoupledMooseVars();
138 262 : if (std::any_of(variable.begin(), variable.end(), [](auto & var) { return !var->isNodal(); }))
139 3 : mooseError("Trying to use a non-nodal variable 'advected_variable' for side advection "
140 : "integral calculation, which is currently not supported.");
141 :
142 128 : return (_use_normal
143 128 : ? _advected_variable[_qp] * RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
144 128 : : _advected_variable[_qp] * RealVectorValue(vel_x, vel_y, vel_z)(_component));
145 : }
146 256 : else if (_advected_mat_prop_supplied)
147 384 : return (_use_normal ? raw_value(_advected_material_property[_qp]) *
148 256 : RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
149 256 : : raw_value(_advected_material_property[_qp]) *
150 384 : RealVectorValue(vel_x, vel_y, vel_z)(_component));
151 : else
152 0 : return (_use_normal ? RealVectorValue(vel_x, vel_y, vel_z) * _normals[_qp]
153 0 : : RealVectorValue(vel_x, vel_y, vel_z)(_component));
154 : }
155 :
156 : template class SideAdvectiveFluxIntegralTempl<false>;
157 : template class SideAdvectiveFluxIntegralTempl<true>;
|