https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ADGateValve1PhaseUserObject.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
11#include "THMIndicesVACE.h"
13#include "Function.h"
14#include "Numerics.h"
15#include "metaphysicl/parallel_numberarray.h"
16#include "metaphysicl/parallel_dualnumber.h"
17#include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
18#include "libmesh/parallel_algebra.h"
19
21
22const std::vector<std::pair<std::string, unsigned int>>
24 std::pair<std::string, unsigned int>("rhoA", THMVACE1D::MASS),
25 std::pair<std::string, unsigned int>("rhouA", THMVACE1D::MOMENTUM),
26 std::pair<std::string, unsigned int>("rhoEA", THMVACE1D::ENERGY)};
27
30{
32
33 params.addRequiredParam<Real>("open_area_fraction",
34 "Fraction of possible flow area that is open");
35 params.addParam<Real>("open_area_fraction_min", 1e-10, "Minimum open area fraction");
36
37 params.addRequiredCoupledVar("A", "Cross-sectional area of connected flow channels");
38 params.addRequiredCoupledVar("rhoA", "rho*A of the connected flow channels");
39 params.addRequiredCoupledVar("rhouA", "rhou*A of the connected flow channels");
40 params.addRequiredCoupledVar("rhoEA", "rhoE*A of the connected flow channels");
41
42 params.addRequiredParam<UserObjectName>("numerical_flux", "Numerical flux user object name");
43
44 params.addRequiredParam<std::string>("component_name", "Name of the associated component");
45
46 params.addClassDescription("Gate valve user object for 1-phase flow");
47
48 params.declareControllable("open_area_fraction");
49
50 return params;
51}
52
55
56 _f_open(getParam<Real>("open_area_fraction")),
57 _f_open_min(getParam<Real>("open_area_fraction_min")),
58
59 _A(adCoupledValue("A")),
60 _rhoA(adCoupledValue("rhoA")),
61 _rhouA(adCoupledValue("rhouA")),
62 _rhoEA(adCoupledValue("rhoEA")),
63
64 _rhoA_jvar(coupled("rhoA")),
65 _rhouA_jvar(coupled("rhouA")),
66 _rhoEA_jvar(coupled("rhoEA")),
67
68 _p(getADMaterialProperty<Real>("p")),
69
70 _numerical_flux(getUserObject<ADNumericalFlux3EqnBase>("numerical_flux")),
71
72 _component_name(getParam<std::string>("component_name")),
73
74 _dir(getMaterialProperty<RealVectorValue>("direction")),
75
76 _solutions(_n_connections),
77 _fluxes(_n_connections, std::vector<ADReal>(THMVACE1D::N_FLUX_OUTPUTS, 0)),
78 _dof_indices(_n_connections, std::vector<dof_id_type>(THMVACE1D::N_FLUX_OUTPUTS, 0)),
79
80 _stored_p(_n_connections),
81
82 _elem_ids(_n_connections),
83 _local_side_ids(_n_connections),
84
85 _areas(_n_connections),
86 _directions(_n_connections)
87{
88}
89
90void
92{
93 _connection_indices.clear();
94
95 std::vector<ADReal> zero(THMVACE1D::N_FLUX_INPUTS, ADReal(0.));
96 for (auto & s : _solutions)
97 s = zero;
98 for (unsigned int i = 0; i < THMVACE1D::N_FLUX_OUTPUTS; i++)
99 {
100 _fluxes[0][i] = 0;
101 _fluxes[1][i] = 0;
102 }
103}
104
105void
107{
108 // Get connection index
109 const unsigned int c = getBoundaryIDIndex();
110 _connection_indices.push_back(c);
111
112 // Store DoF indices
113 for (const auto & varname_eq_index_pair : _varname_eq_index_pairs)
114 {
115 MooseVariable * var = getVar(varname_eq_index_pair.first, 0);
116 auto && dofs = var->dofIndices();
117 mooseAssert(dofs.size() == 1, "There should be only one DoF index.");
118 _dof_indices[c][varname_eq_index_pair.second] = dofs[0];
119 }
120
121 // Store solution vector for connection
122 std::vector<ADReal> U(THMVACE1D::N_FLUX_INPUTS, ADReal(0.));
123 U[THMVACE1D::RHOA] = _rhoA[0];
124 U[THMVACE1D::RHOUA] = _rhouA[0];
125 U[THMVACE1D::RHOEA] = _rhoEA[0];
126 U[THMVACE1D::AREA] = _A[0];
127 _solutions[c] = U;
128
129 // Store element ID and local side ID for connection
130 _elem_ids[c] = _current_elem->id();
132
133 // Store direction and area of channel at junction (used for error-checking)
134 _areas[c] = _A[0];
135 _directions[c] = _dir[0];
136
137 _stored_p[c] = _p[0];
138}
139
140void
142{
143 const auto & junction_uo = static_cast<const ADGateValve1PhaseUserObject &>(uo);
144
145 // Store the data computed/retrieved in the other threads
146 for (unsigned int i = 0; i < junction_uo._connection_indices.size(); i++)
147 {
148 const unsigned int c = junction_uo._connection_indices[i];
149
150 _dof_indices[c] = junction_uo._dof_indices[c];
151 _solutions[c] = junction_uo._solutions[c];
152 _elem_ids[c] = junction_uo._elem_ids[c];
153 _local_side_ids[c] = junction_uo._local_side_ids[c];
154 _areas[c] = junction_uo._areas[c];
155 _directions[c] = junction_uo._directions[c];
156 _stored_p[c] = junction_uo._stored_p[c];
157 }
158}
159
160void
162{
163 // Check direction compatibility
165 mooseError(_component_name, ": The connected channels must be parallel at the junction.");
166
167 for (unsigned int i = 0; i < _n_connections; i++)
168 {
169 processor_id_type owner_proc = _processor_ids[i];
170 comm().broadcast(_elem_ids[i], owner_proc, true);
171 comm().broadcast(_local_side_ids[i], owner_proc, true);
172 comm().broadcast(_solutions[i], owner_proc, true);
173 comm().broadcast(_directions[i], owner_proc, true);
174 comm().broadcast(_areas[i], owner_proc, true);
175 comm().broadcast(_stored_p[i], owner_proc, true);
176 }
177
178 const Real & n1_dot_d1 = _normal[0];
179 const Real d1_dot_d2 = _directions[0] * _directions[1];
180
181 const ADReal & A1 = _areas[0];
182 const ADReal & A2 = _areas[1];
183 const ADReal A = std::min(A1, A2);
184 const ADReal A_flow = _f_open * A;
185
186 if (_f_open > _f_open_min)
187 {
188 // compute flow contribution
189 std::vector<ADReal> U_flow1 = _solutions[0];
190 std::vector<ADReal> U_flow2 = _solutions[1];
191 U_flow1[THMVACE1D::AREA] = A_flow;
192 U_flow2[THMVACE1D::AREA] = A_flow;
193 for (unsigned int i = 0; i < THMVACE1D::N_FLUX_OUTPUTS; i++)
194 {
195 U_flow1[i] *= A_flow / A1;
196 U_flow2[i] *= A_flow / A2;
197 }
198 U_flow2[THMVACE1D::RHOUA] *= d1_dot_d2;
199
201 _local_side_ids[0], _elem_ids[0], true, U_flow1, U_flow2, n1_dot_d1);
202
204 _local_side_ids[0], _elem_ids[0], false, U_flow1, U_flow2, n1_dot_d1);
205 _fluxes[1][THMVACE1D::RHOA] *= d1_dot_d2;
206 _fluxes[1][THMVACE1D::RHOEA] *= d1_dot_d2;
207 }
208
209 // compute wall contribution
210 for (unsigned int c = 0; c < _n_connections; c++)
211 {
212 const ADReal A_wall = _areas[c] - A_flow;
213 _fluxes[c][THMVACE1D::RHOUA] += _stored_p[c] * A_wall;
214 }
215}
216
217const std::vector<ADReal> &
218ADGateValve1PhaseUserObject::getFlux(const unsigned int & connection_index) const
219{
220 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
221
222 return _fluxes[connection_index];
223}
registerMooseObject("ThermalHydraulicsApp", ADGateValve1PhaseUserObject)
DualNumber< Real, DNDerivativeType, true > ADReal
Provides common interfaces for flow junction user objects.
unsigned int getBoundaryIDIndex()
Gets the index of the currently executing boundary within the vector of boundary IDs given to this Si...
static InputParameters validParams()
std::vector< unsigned int > _processor_ids
Owners of each side of the junction.
const unsigned int _n_connections
Number of connected flow channels.
const std::vector< Real > & _normal
Flow channel outward normals or junction inward normals.
Gate valve user object for 1-phase flow.
std::vector< ADReal > _areas
Areas at each connection.
static const std::vector< std::pair< std::string, unsigned int > > _varname_eq_index_pairs
Pairs of variable names vs. their corresponding equation indices.
const ADMaterialProperty< Real > & _p
Pressure material property.
virtual void threadJoin(const UserObject &uo) override
std::vector< unsigned int > _connection_indices
Connection indices for this thread.
const ADVariableValue & _rhoA
rho*A of the connected flow channels
const std::string & _component_name
Name of the associated component.
std::vector< RealVectorValue > _directions
Directions at each connection.
const MaterialProperty< RealVectorValue > & _dir
Direction material property.
std::vector< std::vector< ADReal > > _solutions
Solution vectors for each connection.
std::vector< std::vector< dof_id_type > > _dof_indices
Degree of freedom indices; first index is connection, second is equation.
const Real & _f_open_min
Minimum open area fraction.
std::vector< std::vector< ADReal > > _fluxes
Flux vector.
const std::vector< ADReal > & getFlux(const unsigned int &connection_index) const override
Gets the flux vector for a connection.
ADGateValve1PhaseUserObject(const InputParameters &params)
const ADVariableValue & _A
Cross-sectional area of connected flow channels.
const Real & _f_open
Fraction of possible flow area that is open.
std::vector< unsigned int > _elem_ids
Element IDs for each connection.
std::vector< unsigned int > _local_side_ids
Local side IDs for each connection.
const ADNumericalFlux3EqnBase & _numerical_flux
Numerical flux user object.
std::vector< ADReal > _stored_p
Stored pressure for each connection.
const ADVariableValue & _rhoEA
rho*E*A of the connected flow channels
const ADVariableValue & _rhouA
rho*u*A of the connected flow channels
Base class for computing numerical fluxes for FlowModelSinglePhase.
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)
void mooseError(Args &&... args) const
const std::vector< dof_id_type > & dofIndices() const final
virtual const std::vector< ADReal > & getFlux(const unsigned int iside, const dof_id_type ielem, bool res_side_is_left, const std::vector< ADReal > &UL_1d, const std::vector< ADReal > &UR_1d, Real nLR_dot_d) const
Gets the 1D flux vector for an element/side combination.
const unsigned int & _current_side
const Elem *const & _current_elem
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
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 1D.
bool areParallelVectors(const RealVectorValue &a, const RealVectorValue &b, const Real &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Tests if two real-valued vectors are parallel within some absolute tolerance.