https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ADVolumeJunction1PhaseUserObject.C
Go to the documentation of this file.
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
12#include "THMIndicesVACE.h"
15#include "Numerics.h"
16#include "THMUtils.h"
17#include "metaphysicl/parallel_numberarray.h"
18#include "metaphysicl/parallel_dualnumber.h"
19#include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
20#include "libmesh/parallel_algebra.h"
21
23
26{
28
29 params.addRequiredCoupledVar("A", "Cross-sectional area of connected flow channels");
30 params.addRequiredCoupledVar("rhoA", "rho*A of the connected flow channels");
31 params.addRequiredCoupledVar("rhouA", "rhou*A of the connected flow channels");
32 params.addRequiredCoupledVar("rhoEA", "rhoE*A of the connected flow channels");
33
34 params.addRequiredCoupledVar("rhoV", "rho*V of the junction");
35 params.addRequiredCoupledVar("rhouV", "rho*u*V of the junction");
36 params.addRequiredCoupledVar("rhovV", "rho*v*V of the junction");
37 params.addRequiredCoupledVar("rhowV", "rho*w*V of the junction");
38 params.addRequiredCoupledVar("rhoEV", "rho*E*V of the junction");
39
40 params.addRequiredParam<UserObjectName>("fp", "Fluid properties user object name");
41
42 params.addRequiredParam<Real>("K", "Form loss coefficient [-]");
43 params.addRequiredParam<Real>("A_ref", "Reference area [m^2]");
44
45 params.addParam<bool>("apply_velocity_scaling",
46 false,
47 "Set to true to apply the scaling to the normal velocity. See "
48 "documentation for more information.");
49
51 "Computes and caches flux and residual vectors for a 1-phase volume junction");
52
53 params.declareControllable("K");
54 return params;
55}
56
59
60 _A(adCoupledValue("A")),
61 _rhoA(adCoupledValue("rhoA")),
62 _rhouA(adCoupledValue("rhouA")),
63 _rhoEA(adCoupledValue("rhoEA")),
64
65 _K(getParam<Real>("K")),
66 _A_ref(getParam<Real>("A_ref")),
67
68 _apply_velocity_scaling(getParam<bool>("apply_velocity_scaling")),
69
70 _fp(getUserObject<SinglePhaseFluidProperties>("fp"))
71{
76
83
90
92 for (std::size_t i = 0; i < _n_connections; i++)
93 _numerical_flux_uo[i] = &getUserObjectByName<ADNumericalFlux3EqnBase>(_numerical_flux_names[i]);
94}
95
96void
98{
99 const Real din = _normal[c];
100 const RealVectorValue di = _dir[0];
101 const RealVectorValue ni = di * din;
102 const Real nJi_dot_di = -din;
103
104 std::vector<ADReal> Ui(THMVACE3D::N_FLUX_INPUTS, 0.);
105 Ui[THMVACE3D::RHOA] = _rhoA[0];
106 Ui[THMVACE3D::RHOUA] = _rhouA[0] * di(0);
107 Ui[THMVACE3D::RHOVA] = _rhouA[0] * di(1);
108 Ui[THMVACE3D::RHOWA] = _rhouA[0] * di(2);
109 Ui[THMVACE3D::RHOEA] = _rhoEA[0];
110 Ui[THMVACE3D::AREA] = _A[0];
111
112 const auto flux_3d = compute3DFlux(*(_numerical_flux_uo[c]), Ui, ni);
113
115 _flux[c][THMVACE1D::MASS] = flux_3d[THMVACE3D::MASS] * nJi_dot_di;
117 _flux[c][THMVACE1D::ENERGY] = flux_3d[THMVACE3D::ENERGY] * nJi_dot_di;
118
119 const bool is_primary_connection = (c == 0);
120 const auto residual = computeResidual(flux_3d, Ui, ni, is_primary_connection);
121
122 for (const auto i : index_range(_residual))
123 _residual[i] += residual[i];
124}
125
126std::vector<ADReal>
128 const std::vector<ADReal> & Ui,
129 const RealVectorValue & ni) const
130{
131 using std::abs, std::max, std::min;
132
133 const RealVectorValue nJi = -ni;
134
135 RealVectorValue t1, t2;
137
138 const auto & Ai = Ui[THMVACE3D::AREA];
139
145
146 std::vector<ADReal> UJi(THMVACE3D::N_FLUX_INPUTS, 0.);
147 UJi[THMVACE3D::RHOA] = rhoV / _volume * Ai;
149 {
150 const auto & rhoAi = Ui[THMVACE3D::RHOA];
151 const auto & rhouAi = Ui[THMVACE3D::RHOUA];
152 const auto & rhovAi = Ui[THMVACE3D::RHOVA];
153 const auto & rhowAi = Ui[THMVACE3D::RHOWA];
154 const auto & rhoEAi = Ui[THMVACE3D::RHOEA];
155
156 const ADRealVectorValue uveci(rhouAi / rhoAi, rhovAi / rhoAi, rhowAi / rhoAi);
157 const ADReal uni = uveci * nJi;
158
159 const ADReal rhoJ = rhoV / _volume;
160 const ADReal vJ = 1.0 / rhoJ;
161 const ADRealVectorValue uvecJ(rhouV / rhoV, rhovV / rhoV, rhowV / rhoV);
162 const ADReal eJ = rhoEV / rhoV - 0.5 * uvecJ * uvecJ;
163
164 const ADReal unJ = uvecJ * nJi;
165 const ADReal ut1J = uvecJ * t1;
166 const ADReal ut2J = uvecJ * t2;
167
168 const ADReal rhoi = rhoAi / Ai;
169 const ADReal vi = 1.0 / rhoi;
170 const ADReal ei = rhoEAi / rhoAi - 0.5 * uni * uni;
171
172 const ADReal ci = _fp.c_from_v_e(vi, ei);
173 const ADReal cJ = _fp.c_from_v_e(vJ, eJ);
174 const ADReal cmax = max(ci, cJ);
175
176 const ADReal uni_sign = (uni > 0) - (uni < 0);
177 const ADReal factor = 0.5 * (1.0 - uni_sign) * min(abs(uni - unJ) / cmax, 1.0);
178
179 const ADReal unJ_mod = uni - factor * (uni - unJ);
180 const ADRealVectorValue uvecJ_mod = unJ_mod * nJi + ut1J * t1 + ut2J * t2;
181 const ADReal EJ_mod = eJ + 0.5 * uvecJ_mod * uvecJ_mod;
182
183 UJi[THMVACE3D::RHOUA] = rhoJ * uvecJ_mod(0) * Ai;
184 UJi[THMVACE3D::RHOVA] = rhoJ * uvecJ_mod(1) * Ai;
185 UJi[THMVACE3D::RHOWA] = rhoJ * uvecJ_mod(2) * Ai;
186 UJi[THMVACE3D::RHOEA] = rhoJ * EJ_mod * Ai;
187 }
188 else
189 {
190 UJi[THMVACE3D::RHOUA] = rhouV / _volume * Ai;
191 UJi[THMVACE3D::RHOVA] = rhovV / _volume * Ai;
192 UJi[THMVACE3D::RHOWA] = rhowV / _volume * Ai;
193 UJi[THMVACE3D::RHOEA] = rhoEV / _volume * Ai;
194 }
195 UJi[THMVACE3D::AREA] = Ai;
196
197 std::vector<ADReal> FL, FR;
198 numerical_flux.calcFlux(UJi, Ui, nJi, t1, t2, FL, FR);
199
200 return FL;
201}
202
203std::vector<ADReal>
204ADVolumeJunction1PhaseUserObject::computeResidual(const std::vector<ADReal> & flux_3d,
205 const std::vector<ADReal> & Ui,
206 const RealVectorValue & ni,
207 bool is_primary_connection) const
208{
209 using std::abs;
210
211 const RealVectorValue nJi = -ni;
212
213 RealVectorValue t1, t2;
215
216 const auto & Ai = Ui[THMVACE3D::AREA];
217
223
224 const ADReal rhoJ = rhoV / _volume;
225 const ADReal vJ = 1.0 / rhoJ;
226 const ADRealVectorValue uvecJ(rhouV / rhoV, rhovV / rhoV, rhowV / rhoV);
227 const ADReal eJ = rhoEV / rhoV - 0.5 * uvecJ * uvecJ;
228 const ADReal pJ = _fp.p_from_v_e(vJ, eJ);
229
230 std::vector<ADReal> residual(_n_scalar_eq, 0.0);
231
232 if (is_primary_connection && std::abs(_K) > 1e-10)
233 {
234 const auto & rhoAi = Ui[THMVACE3D::RHOA];
235 const auto & rhouAi = Ui[THMVACE3D::RHOUA];
236 const auto & rhovAi = Ui[THMVACE3D::RHOVA];
237 const auto & rhowAi = Ui[THMVACE3D::RHOWA];
238 const auto & rhoEAi = Ui[THMVACE3D::RHOEA];
239
240 const ADRealVectorValue uveci(rhouAi / rhoAi, rhovAi / rhoAi, rhowAi / rhoAi);
241 const ADReal uni = uveci * nJi;
242
243 const ADReal v_in = THM::v_from_rhoA_A(rhoAi, Ai);
244 const ADReal rhouA2 = rhouAi * rhouAi;
245 const ADReal e_in = rhoEAi / rhoAi - 0.5 * rhouA2 / (rhoAi * rhoAi);
246 const ADReal p_in = _fp.p_from_v_e(v_in, e_in);
247 const ADReal s0_in = _fp.s_from_v_e(v_in, e_in);
248 const ADReal T_in = _fp.T_from_v_e(v_in, e_in);
249 const ADReal h_in = _fp.h_from_p_T(p_in, T_in);
250 const ADReal velin2 = uni * uni;
251 const ADReal h0_in = h_in + 0.5 * velin2;
252 const ADReal p0_in = _fp.p_from_h_s(h0_in, s0_in);
253 ADReal S_loss;
254 if (_A_ref == 0)
255 S_loss = _K * (p0_in - p_in) * Ai;
256 else
257 S_loss = _K * (p0_in - p_in) * _A_ref;
258 if (uni > 0) // flow is out of the junction
259 {
260 residual[VolumeJunction1Phase::RHOUV_INDEX] -= ni(0) * S_loss;
261 residual[VolumeJunction1Phase::RHOVV_INDEX] -= ni(1) * S_loss;
262 residual[VolumeJunction1Phase::RHOWV_INDEX] -= ni(2) * S_loss;
263 }
264 else
265 {
266 residual[VolumeJunction1Phase::RHOUV_INDEX] += ni(0) * S_loss;
267 residual[VolumeJunction1Phase::RHOVV_INDEX] += ni(1) * S_loss;
268 residual[VolumeJunction1Phase::RHOWV_INDEX] += ni(2) * S_loss;
269 }
270 residual[VolumeJunction1Phase::RHOEV_INDEX] += S_loss * abs(uni);
271 }
272
273 const ADRealVectorValue flux_mom_n = flux_3d[THMVACE3D::MOM_NORM] * nJi +
274 flux_3d[THMVACE3D::MOM_TAN1] * t1 +
275 flux_3d[THMVACE3D::MOM_TAN2] * t2;
276 const RealVectorValue ex(1, 0, 0);
277 const RealVectorValue ey(0, 1, 0);
278 const RealVectorValue ez(0, 0, 1);
279
281 residual[VolumeJunction1Phase::RHOUV_INDEX] -= -flux_mom_n * ex - pJ * ni(0) * Ai;
282 residual[VolumeJunction1Phase::RHOVV_INDEX] -= -flux_mom_n * ey - pJ * ni(1) * Ai;
283 residual[VolumeJunction1Phase::RHOWV_INDEX] -= -flux_mom_n * ez - pJ * ni(2) * Ai;
285
286 return residual;
287}
288
289void
296
297std::vector<const MooseVariableBase *>
299{
300 std::vector<const MooseVariableBase *> vars(THMVACE1D::N_FLUX_OUTPUTS);
301 vars[THMVACE1D::RHOA] = getVar("rhoA", 0);
302 vars[THMVACE1D::RHOUA] = getVar("rhouA", 0);
303 vars[THMVACE1D::RHOEA] = getVar("rhoEA", 0);
304
305 return vars;
306}
307
308std::vector<const MooseVariableBase *>
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("ThermalHydraulicsApp", ADVolumeJunction1PhaseUserObject)
char ** vars
const unsigned int _n_connections
Number of connected flow channels.
const std::vector< Real > & _normal
Flow channel outward normals or junction inward normals.
const MaterialProperty< RealVectorValue > & _dir
Direction of the element connected to the junction.
Base class for computing numerical fluxes for FlowModelSinglePhase.
Computes and caches flux and residual vectors for a 1-phase volume junction.
virtual std::vector< const MooseVariableBase * > getFlowChannelVariables() const override
Gets the flow channel variables.
const SinglePhaseFluidProperties & _fp
Single-phase fluid properties user object.
const ADVariableValue & _rhoEA
rho*E*A of the connected flow channels
std::vector< const ADNumericalFlux3EqnBase * > _numerical_flux_uo
Vector of numerical flux user objects for each connected flow channel.
std::vector< ADReal > computeResidual(const std::vector< ADReal > &flux_3d, const std::vector< ADReal > &Ui, const RealVectorValue &ni, bool is_primary_connection) const
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.
const bool _apply_velocity_scaling
Apply velocity scaling?
const ADVariableValue & _rhouA
rho*u*A of the connected flow channels
virtual std::vector< const MooseVariableBase * > getJunctionVariables() const override
Gets the junction variables.
const ADVariableValue & _rhoA
rho*A of the connected flow channels
ADVolumeJunction1PhaseUserObject(const InputParameters &params)
std::vector< ADReal > compute3DFlux(const ADNumericalFlux3EqnBase &numerical_flux, const std::vector< ADReal > &Ui, const RealVectorValue &ni) const
const ADVariableValue & _A
Cross-sectional area of connected flow channels.
Base class for computing and caching flux and residual vectors for a volume junction.
std::vector< const ADVariableValue * > _junction_var_values
const ADVariableValue & coupledJunctionValue(const std::string &var_name, unsigned int i=0) const
Gets an AD junction variable value.
std::vector< std::vector< ADReal > > _flux
Cached flux vector for each connection.
std::vector< std::string > _scalar_variable_names
Vector of coupled variable names for each scalar variable.
const MooseVariableBase * getJunctionVar(const std::string &var_name, unsigned int i=0) const
Gets a junction variable.
std::vector< std::string > _flow_variable_names
Vector of coupled variable names for each flow variable.
unsigned int _n_scalar_eq
Number of scalar residual components.
const std::vector< UserObjectName > & _numerical_flux_names
Names of numerical flux user objects for each connected flow channel.
std::vector< ADReal > _residual
Cached scalar residual vector.
const Real & _volume
Volume of the junction.
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
virtual void calcFlux(const std::vector< ADReal > &UL_3d, const std::vector< ADReal > &UR_3d, const RealVectorValue &nLR, const RealVectorValue &t1, const RealVectorValue &t2, std::vector< ADReal > &FL, std::vector< ADReal > &FR) const =0
Calculates the 3D flux vectors given "left" and "right" states.
Common class for single phase fluid properties.
virtual void finalize()=0
static const unsigned int N_EQ
Number of equations for the junction.
const Parallel::Communicator & comm() const
static const unsigned int N_FLUX_OUTPUTS
Number of numerical flux function outputs for 1D.
static const unsigned int N_FLUX_INPUTS
Number of numerical flux function inputs for 3D.
void v_from_rhoA_A(Real rhoA, Real A, Real &v, Real &dv_drhoA)
Computes specific volume and its derivatives from rho*A, and area.
Definition Numerics.C:100
void computeOrthogonalDirections(const RealVectorValue &n_unnormalized, RealVectorValue &t1, RealVectorValue &t2)
Computes two unit vectors orthogonal to the given vector.
Definition THMUtils.C:22