https://mooseframework.inl.gov
ADJunctionParallelChannels1PhaseUserObject.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"
13 #include "VolumeJunction1Phase.h"
14 #include "NumericalFlux3EqnBase.h"
15 #include "Numerics.h"
16 #include "LoggingInterface.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  params.addRequiredParam<std::string>("component_name", "Name of the associated component");
29  params.addRequiredParam<RealVectorValue>("dir_c0", "Direction of the first connection");
30 
31  params.addClassDescription("Computes and caches flux and residual vectors for a 1-phase junction "
32  "that connects flow channels that are parallel");
33 
34  return params;
35 }
36 
38  const InputParameters & params)
40 
41  _p(getADMaterialProperty<Real>("p")),
42 
43  _dir_c0(getParam<RealVectorValue>("dir_c0")),
44 
45  _stored_pA(_n_connections),
46  _areas(_n_connections),
47  _is_inlet(_n_connections),
48 
49  _component_name(getParam<std::string>("component_name"))
50 {
51 }
52 
53 void
55 {
57 
58  _c_in.clear();
59  _c_out.clear();
60 }
61 
62 void
64 {
66 
67  const Real din = _normal[c];
68  const Point di = _dir[0];
69  const Point ni = di * din;
70 
76 
77  const ADReal vJ = THM::v_from_rhoA_A(rhoV, _volume);
78  const ADRealVectorValue rhouV_vec(rhouV, rhovV, rhowV);
79  const ADReal rhouV2 = rhouV_vec * rhouV_vec;
80  const ADReal eJ = rhoEV / rhoV - 0.5 * rhouV2 / (rhoV * rhoV);
81  const ADReal pJ = _fp.p_from_v_e(vJ, eJ);
82 
86 
87  if (c == 0)
88  {
90  _d_flow = _dir[0];
91  else
92  // FIXME: _d_flow should be again ADRealVectorValue when we have parallel comm on
93  // ADRealVectorValue
94  _d_flow =
96  }
97 
100  ": Connected flow channels are not parallel, use VolumeJunction1Phase "
101  "component instead.");
102 
103  _areas[c] = _A[0];
105  _stored_pA[c] = _p[0] * _A[0];
106 }
107 
108 void
110 {
112 
113  const auto & jpc_uo = static_cast<const ADJunctionParallelChannels1PhaseUserObject &>(uo);
114 
115  // Store the data computed/retrieved in the other threads
116  for (unsigned int i = 0; i < jpc_uo._connection_indices.size(); i++)
117  {
118  const unsigned int c = jpc_uo._connection_indices[i];
119 
120  _areas[c] = jpc_uo._areas[c];
121  _is_inlet[c] = jpc_uo._is_inlet[c];
122  _stored_pA[c] = jpc_uo._stored_pA[c];
123  if (c == 0)
124  _d_flow = jpc_uo._d_flow;
125  }
126 }
127 
128 void
130 {
131  for (unsigned int i = 0; i < _n_connections; i++)
132  {
133  processor_id_type owner_proc = _processor_ids[i];
134  comm().broadcast(_areas[i], owner_proc, true);
135  comm().broadcast(_stored_pA[i], owner_proc, true);
136  // because std::vector<bool> is very special
137  bool b = _is_inlet[i];
138  comm().broadcast(b, owner_proc, true);
139  _is_inlet[i] = b;
140  }
141  comm().broadcast(_d_flow, _processor_ids[0], true);
142 
143  ADReal Ain_total = 0;
144  ADReal pAin_total = 0;
145  ADReal pAout_total = 0;
146  ADReal Aout_total = 0;
147  for (unsigned int c = 0; c < _n_connections; c++)
148  {
149  if (_is_inlet[c] == true)
150  {
151  Ain_total += _areas[c];
152  pAin_total += _stored_pA[c];
153  _c_in.push_back(c);
154  }
155  else
156  {
157  Aout_total += _areas[c];
158  pAout_total += _stored_pA[c];
159  _c_out.push_back(c);
160  }
161  }
162 
163  ADReal p_wall = 0;
164  ADReal A_wall = 0;
165  RealVectorValue d_wall;
166 
167  if (Aout_total > Ain_total)
168  {
169  if (Aout_total > 1e-15)
170  {
171  p_wall = pAout_total / Aout_total;
172  _c_wall = _c_out;
173  }
174  else
175  {
176  p_wall = 0;
177  }
178  A_wall = Aout_total - Ain_total;
179  d_wall = _d_flow;
180  }
181  else
182  {
183  if (Ain_total > 1e-15)
184  {
185  p_wall = pAin_total / Ain_total;
186  _c_wall = _c_in;
187  }
188  else
189  {
190  p_wall = 0;
191  }
192  A_wall = Ain_total - Aout_total;
193  d_wall = -_d_flow;
194  }
195 
196  for (unsigned int i = 0; i < _n_scalar_eq; i++)
197  comm().sum(_residual[i]);
198 
199  _residual[VolumeJunction1Phase::RHOUV_INDEX] -= d_wall(0) * p_wall * A_wall;
200  _residual[VolumeJunction1Phase::RHOVV_INDEX] -= d_wall(1) * p_wall * A_wall;
201  _residual[VolumeJunction1Phase::RHOWV_INDEX] -= d_wall(2) * p_wall * A_wall;
202 }
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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
const SinglePhaseFluidProperties & _fp
Single-phase fluid properties user object.
std::vector< ADReal > _areas
Areas at each connection.
auto raw_value(const Eigen::Map< T > &in)
const Parallel::Communicator & comm() const
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.
unsigned int _n_scalar_eq
Number of scalar residual components.
bool isOutlet(Real vel, Real normal)
Determine if outlet boundary condition should be applied.
Definition: Numerics.C:247
std::vector< bool > _is_inlet
Check if the connection is an inlet.
registerMooseObject("ThermalHydraulicsApp", ADJunctionParallelChannels1PhaseUserObject)
Computes and caches flux and residual vectors for a 1-phase junction that connects flow channels that...
std::vector< unsigned int > _c_in
Connection index for inlet flow channel connections.
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.
Definition: Numerics.C:26
const unsigned int _n_connections
Number of connected flow channels.
RealVectorValue _d_flow
Flow direction for the first connection.
std::vector< unsigned int > _c_out
Connection index for outlet flow channel connections.
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::vector< ADReal > _residual
Cached scalar residual vector.
const Real & _volume
Volume of the junction.
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.
const MaterialProperty< RealVectorValue > & _dir
Direction of the element connected to the junction.
uint8_t processor_id_type
virtual void threadJoin(const UserObject &uo) override
const ADMaterialProperty< Real > & _p
Pressure material property.
Computes and caches flux and residual vectors for a 1-phase volume junction.
std::vector< unsigned int > _processor_ids
Owners of each side of the junction.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
const ADVariableValue & _A
Cross-sectional area of connected flow channels.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
RealVectorValue _dir_c0
Channel direction for the first connection.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
const std::vector< Real > & _normal
Flow channel outward normals or junction inward normals.
const ADVariableValue & _rhouA
rho*u*A of the connected flow channels
std::vector< unsigned int > _c_wall
Connection index for connections that contribute to the wall pressure.
const std::string & _component_name
Name of the associated component.