https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ADSpecificImpulse1Phase.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 "Numerics.h"
13#include "THMIndicesVACE.h"
14#include "ADBoundaryFluxBase.h"
15
17
20{
22 params.addRequiredParam<Real>("p_exit", "Outlet pressure at nozzle exit");
23 params.addRequiredParam<UserObjectName>("fp", "Single-phase fluid properties");
24 params.addParam<Real>(
25 "bisection_tolerance", 1e-4, "Tolerance for bisection to find h(entropy_in, p_out)");
26 params.addParam<unsigned int>(
27 "bisection_max_it",
28 100,
29 "Maximum number of iterations for bisection to find h(entropy_in, p_out)");
30 params.addParam<bool>("cumulative",
31 true,
32 "If specific impulse is accumulated over timesteps. If false, then "
33 "instantaneous value is computed");
34 params.addCoupledVar("variables", "Single-phase flow variables");
35 params.set<std::vector<VariableName>>("variables") = {"rhoA", "rhouA", "rhoEA", "A"};
36 params.addClassDescription("Estimates specific impulse from fluid state at a boundary");
37 return params;
38}
39
41 : SidePostprocessor(parameters),
42 _n_components(THMVACE1D::N_FLUX_INPUTS),
43 _boundary_name(getParam<std::vector<BoundaryName>>("boundary")[0]),
44 _boundary_uo_name(_boundary_name + ":boundary_uo"),
45 _boundary_uo(getUserObjectByName<ADBoundaryFluxBase>(_boundary_uo_name)),
46 _p_exit(getParam<Real>("p_exit")),
47 _H(getADMaterialPropertyByName<Real>("H")),
48 _v(getADMaterialPropertyByName<Real>("v")),
49 _e(getADMaterialPropertyByName<Real>("e")),
50 _T(getADMaterialPropertyByName<Real>("T")),
51 _fp(getUserObject<SinglePhaseFluidProperties>("fp")),
52 _tol(getParam<Real>("bisection_tolerance")),
53 _max_nit(getParam<unsigned int>("bisection_max_it")),
54 _cumulative(getParam<bool>("cumulative")),
55 _accumulated_mass_flow_rate(declareRestartableData<Real>("accumulated_mass_flow_rate", 0)),
56 _accumulated_thrust(declareRestartableData<Real>("accumulated_thrust", 0)),
57 _value(0.0)
58{
60 paramError("cumulative", "Must be false unless problem is transient");
61
62 for (unsigned int i = 0; i < _n_components; i++)
63 _U.push_back(&adCoupledValue("variables", i));
64}
65
66void
73
74void
80
81Real
83{
84 return _value;
85}
86
87void
102
103void
105{
106 for (unsigned int qp = 0; qp < _qrule->n_points(); qp++)
107 {
108 std::vector<ADReal> U(_n_components);
109 for (unsigned int i = 0; i < _n_components; i++)
110 U[i] = (*_U[i])[qp];
111
112 const auto & flux = _boundary_uo.getFlux(_current_side, _current_elem->id(), U, _normals[qp]);
113
114 _mass_flow_rate += std::abs(MetaPhysicL::raw_value(flux[0]));
115
116 // get entropy at inlet (= entropy at outlet because process is isentropic)
117 Real entropy_in =
119
120 // compute outlet enthalpy from entropy at inlet (isentropic flow)
121 // and pressure at outlet, need to do bisection because h_from_s_p does not
122 // exist, it is better to work with temperature because s(p, T) is available
123
124 // upper bound of temperature is the inlet temperature
125 Real T_up = MetaPhysicL::raw_value(_T[qp]);
126
127 // compute entropy associated with T_up
128 Real entropy_up = _fp.s_from_p_T(_p_exit, T_up);
129
130 // lower bound for temperature is 0.1 K
131 Real T_low = 0.1;
132
133 // compute entropy associated with T_low
134 Real entropy_low = _fp.s_from_p_T(_p_exit, T_low);
135
136 // compute the midpoint temperature
137 Real T_mid = 0.5 * (T_up + T_low);
138
139 // the current guess for entropy
140 Real entropy_mid = _fp.s_from_p_T(_p_exit, T_mid);
141
142 // main bisection loop
143 unsigned int nit = 0;
144 while (std::abs(1 - entropy_mid / entropy_in) > _tol)
145 {
146 // check if we are over/underestimating to select either up/down
147 if ((entropy_mid - entropy_in > 0) == (entropy_up - entropy_low > 0))
148 {
149 T_up = T_mid;
150 entropy_up = entropy_mid;
151 }
152 else
153 {
154 T_low = T_mid;
155 entropy_low = entropy_mid;
156 }
157
158 // update guess for T_mid
159 T_mid = 0.5 * (T_up + T_low);
160
161 // update the guess for entropy
162 entropy_mid = _fp.s_from_p_T(_p_exit, T_mid);
163
164 ++nit;
165
166 if (nit == _max_nit)
167 {
168 mooseDoOnce(mooseWarning("Bisection in ADSpecificImpulse1Phase did not converge"));
169 break;
170 }
171 }
172
173 // the enthalpy evaluated at _p_exit and T_mid
174 Real h_exit = _fp.h_from_p_T(_p_exit, T_mid);
175
176 // compute outlet speed
177 Real vel_exit = std::sqrt(2.0 * (MetaPhysicL::raw_value(_H[qp]) - h_exit));
178 _thrust += std::abs(vel_exit * MetaPhysicL::raw_value(flux[0]));
179 }
180}
registerMooseObject("ThermalHydraulicsApp", ADSpecificImpulse1Phase)
const std::vector< double > y
void ErrorVector unsigned int
A base class for computing/caching fluxes at boundaries.
virtual const std::vector< ADReal > & getFlux(unsigned int iside, dof_id_type ielem, const std::vector< ADReal > &uvec1, const RealVectorValue &dwave) const
Get the boundary flux vector.
Estimates specific impulse from fluid state at the boundary.
const unsigned int _n_components
Number of components in the solution vector used to compute the flux.
const Real _p_exit
the outlet pressure, user supplied value
std::vector< const ADVariableValue * > _U
Variables to pass to boundary flux user object, in the correct order.
ADSpecificImpulse1Phase(const InputParameters &parameters)
virtual Real getValue() const override
const SinglePhaseFluidProperties & _fp
fluid property user object
const bool _cumulative
if the specific impulse is accumulated over timesteps
Real _value
The value of this post-processor.
Real _mass_flow_rate
total mass flow rate
Real & _accumulated_mass_flow_rate
accumulated mass flow rate over time
const ADMaterialProperty< Real > & _T
fluid temperature
const ADBoundaryFluxBase & _boundary_uo
Boundary user object.
const ADMaterialProperty< Real > & _e
internal energy
const unsigned int _max_nit
maximum number of iterations for bisection
virtual void execute() override
virtual void finalize() override
const ADMaterialProperty< Real > & _v
specific volume
virtual void initialize() override
virtual void threadJoin(const UserObject &y) override
const ADMaterialProperty< Real > & _H
the total enthalpy including mechanical energy
const Real _tol
bisection tolerance
static InputParameters validParams()
Real & _accumulated_thrust
accumulated thrust over time
const ADVariableValue & adCoupledValue(const std::string &var_name, unsigned int comp=0) const
virtual bool isTransient() const override
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)
T & set(const std::string &name, bool quiet_mode=false)
void addCoupledVar(const std::string &name, const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
void mooseWarning(Args &&... args) const
static InputParameters validParams()
const unsigned int & _current_side
const QBase *const & _qrule
const MooseArray< Point > & _normals
const Elem *const & _current_elem
Common class for single phase fluid properties.
void gatherSum(T &value)
FEProblemBase & _fe_problem
auto raw_value(const Eigen::Map< T > &in)
static const Real gravity_const
Definition Numerics.h:26