22 "Solver class for interwrapper of assemblies in a triangular-lattice arrangement");
40 else if (Re >= 1 and Re < 5000)
45 else if (Re >= 5000 and Re < 30000)
61 unsigned int last_node = (iblock + 1) *
_block_size;
64 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
68 auto dz = z_grid[iz] - z_grid[iz - 1];
69 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
73 auto rho_in = (*_rho_soln)(node_in);
74 auto rho_out = (*_rho_soln)(node_out);
75 auto mu_in = (*_mu_soln)(node_in);
76 auto S = (*_S_flow_soln)(node_in);
77 auto w_perim = (*_w_perim_soln)(node_in);
79 auto Dh_i = 4.0 *
S / w_perim;
86 auto mass_term2 = -2.0 * (*_mdot_soln)(node_out) * (*
_SumWij_soln)(node_out) /
S / rho_in;
88 auto crossflow_term = 0.0;
89 auto turbulent_term = 0.0;
91 unsigned int counter = 0;
95 unsigned int ii_ch = chans.first;
96 unsigned int jj_ch = chans.second;
101 auto rho_i = (*_rho_soln)(node_in_i);
102 auto rho_j = (*_rho_soln)(node_in_j);
103 auto Si = (*_S_flow_soln)(node_in_i);
104 auto Sj = (*_S_flow_soln)(node_in_j);
107 if (
_Wij(i_gap, iz) > 0.0)
108 u_star = (*_mdot_soln)(node_out_i) / Si / rho_i;
110 u_star = (*_mdot_soln)(node_out_j) / Sj / rho_j;
115 turbulent_term +=
_WijPrime(i_gap, iz) * (2 * (*_mdot_soln)(node_out) / rho_in /
S -
120 turbulent_term *=
_CT;
122 auto Re = (((*_mdot_soln)(node_in) /
S) * Dh_i / mu_in);
124 auto ki = k_grid[i_ch][iz - 1];
125 auto friction_term = (fi * dz / Dh_i + ki) * 0.5 * (
std::pow((*
_mdot_soln)(node_out), 2.0)) /
127 auto gravity_term =
_g_grav * (*_rho_soln)(node_out)*dz *
S;
128 auto DP =
std::pow(
S, -1.0) * (time_term + mass_term1 + mass_term2 + crossflow_term +
129 turbulent_term + friction_term + gravity_term);
138 unsigned int last_node = (iblock + 1) *
_block_size;
139 unsigned int first_node = iblock *
_block_size + 1;
143 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
150 name(),
" : Calculation of negative Enthalpy h_out = : ", h_out,
" Axial Level= : ", 0);
156 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
159 auto dz = z_grid[iz] - z_grid[iz - 1];
163 Real gedge_ave = 0.0;
166 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
172 auto Si = (*_S_flow_soln)(node_in);
173 auto mdot_in = (*_mdot_soln)(node_in);
174 mdot_sum = mdot_sum + mdot_in;
175 si_sum = si_sum + Si;
178 gedge_ave = mdot_sum / si_sum;
180 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
186 auto mdot_in = (*_mdot_soln)(node_in);
187 auto h_in = (*_h_soln)(node_in);
188 auto volume = dz * (*_S_flow_soln)(node_in);
189 auto mdot_out = (*_mdot_soln)(node_out);
192 Real sumWijPrimeDhij = 0.0;
196 if (z_grid[iz] > unheated_length_entry && z_grid[iz] <= unheated_length_entry + heated_length)
197 added_enthalpy = ((*_q_prime_soln)(node_out) + (*
_q_prime_soln)(node_in)) * dz / 2.0;
199 added_enthalpy = 0.0;
203 Real sweep_enthalpy = 0.0;
209 const Real & wire_lead_length = 0.0;
210 const Real & wire_diameter = 0.0;
212 auto w = assembly_diameter + gap;
214 std::acos(wire_lead_length /
215 std::sqrt(
std::pow(wire_lead_length, 2) +
220 auto cs_t = 0.75 *
std::pow(wire_lead_length / assembly_diameter, 0.3);
221 auto ar2 =
libMesh::pi * (assembly_diameter + wire_diameter) * wire_diameter / 4.0;
222 auto a2p =
pitch * (w - assembly_diameter / 2.0) -
224 auto Sij_in = dz * gap;
225 auto Sij_out = dz * gap;
226 auto wsweep_in = gedge_ave * cs_t *
std::pow((ar2 / a2p), 0.5) * std::tan(theta) * Sij_in;
227 auto wsweep_out = gedge_ave * cs_t *
std::pow((ar2 / a2p), 0.5) * std::tan(theta) * Sij_out;
228 auto sweep_hin = (*_h_soln)(node_sin);
229 auto sweep_hout = (*_h_soln)(node_in);
230 sweep_enthalpy = (wsweep_in * sweep_hin - wsweep_out * sweep_hout);
234 unsigned int counter = 0;
238 unsigned int ii_ch = chans.first;
240 unsigned int jj_ch = chans.second;
245 if (
_Wij(i_gap, iz) > 0.0)
246 h_star = (*_h_soln)(node_in_i);
247 else if (
_Wij(i_gap, iz) < 0.0)
248 h_star = (*_h_soln)(node_in_j);
251 sumWijPrimeDhij +=
_WijPrime(i_gap, iz) * (2 * (*_h_soln)(node_in) - (*
_h_soln)(node_in_j) -
271 dist_ij =
pitch / std::sqrt(3);
278 0.66 * (
pitch / assembly_diameter) *
282 e_cond += 0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
287 e_cond += -0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
297 auto Si = (*_S_flow_soln)(node_in_i);
298 auto dist_ij = z_grid[iz] - z_grid[iz - 1];
300 e_cond += 0.5 * (thcon_i + thcon_j) * Si * ((*
_T_soln)(node_in_j) - (*
_T_soln)(node_in_i)) /
312 auto Si = (*_S_flow_soln)(node_in_i);
313 auto dist_ij = z_grid[iz + 1] - z_grid[iz];
314 e_cond += 0.5 * (thcon_i + thcon_j) * Si * ((*
_T_soln)(node_in_j) - (*
_T_soln)(node_in_i)) /
321 (mdot_in * h_in - sumWijh - sumWijPrimeDhij + added_enthalpy + e_cond + sweep_enthalpy +
328 " : Calculation of negative Enthalpy h_out = : ",
342 _console <<
"Executing subchannel solver\n";
344 unsigned int P_it = 0;
348 while (P_error >
_P_tol && P_it < P_it_max)
353 _console <<
"Reached maximum number of axial pressure iterations" << std::endl;
356 _console <<
"Solving Outer Iteration : " << P_it << std::endl;
357 auto P_L2norm_old_axial =
_P_soln->L2norm();
358 for (
unsigned int iblock = 0; iblock <
_n_blocks; iblock++)
362 auto T_block_error = 1.0;
364 _console <<
"Solving Block: " << iblock <<
" From first level: " << first_level
365 <<
" to last level: " << last_level << std::endl;
372 _console <<
"Reached maximum number of temperature iterations for block: " << iblock
376 auto T_L2norm_old_block =
_T_soln->L2norm();
396 _aux->solution().close();
398 auto T_L2norm_new =
_T_soln->L2norm();
400 std::abs((T_L2norm_new - T_L2norm_old_block) / (T_L2norm_old_block + 1E-14));
401 _console <<
"T_block_error: " << T_block_error << std::endl;
404 auto P_L2norm_new_axial =
_P_soln->L2norm();
406 std::abs((P_L2norm_new_axial - P_L2norm_old_axial) / (P_L2norm_old_axial +
_P_out + 1E-14));
407 _console <<
"P_error :" << P_error << std::endl;
411 _console <<
"Finished executing subchannel solver\n";
412 _aux->solution().close();
415 auto power_out = 0.0;
416 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
420 power_in += (*_mdot_soln)(node_in) * (*
_h_soln)(node_in);
421 power_out += (*_mdot_soln)(node_out) * (*
_h_soln)(node_out);
425 auto Total_surface_area = 0.0;
426 auto mass_flow_in = 0.0;
427 auto mass_flow_out = 0.0;
428 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
432 Total_surface_area += (*_S_flow_soln)(node_in);
433 mass_flow_in += (*_mdot_soln)(node_in);
434 mass_flow_out += (*_mdot_soln)(node_out);
436 auto h_bulk_out = power_out / mass_flow_out;
437 auto T_bulk_out =
_fp->T_from_p_h(
_P_out, h_bulk_out);
439 _console <<
" ======================================= " << std::endl;
440 _console <<
" ======== Subchannel Print Outs ======== " << std::endl;
441 _console <<
" ======================================= " << std::endl;
442 _console <<
"Total Surface Area :" << Total_surface_area <<
" m^2" << std::endl;
443 _console <<
"Bulk coolant temperature at outlet :" << T_bulk_out <<
" K" << std::endl;
444 _console <<
"Power added to coolant is: " << power_out - power_in <<
" Watt" << std::endl;
445 _console <<
"Mass in: " << mass_flow_in <<
" kg/sec" << std::endl;
446 _console <<
"Mass out: " << mass_flow_out <<
" kg/sec" << std::endl;
447 _console <<
" ======================================= " << std::endl;
const bool _compute_density
Flag that activates or deactivates the calculation of density.
virtual const std::vector< std::vector< Real > > & getKGrid() const
Get axial cell location and value of loss coefficient.
virtual Real computeFrictionFactor(Real Re) override
Computes the axial friction factor for the sodium coolant and for each subchannel.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
registerMooseObject("SubChannelApp", TriInterWrapper1PhaseProblem)
std::unique_ptr< SolutionHandle > _P_soln
virtual const unsigned int & getNumOfAxialCells() const
Return the number of axial cells.
const int & _T_maxit
Maximum iterations for the inner temperature loop.
const Real & _P_tol
Convergence tolerance for the pressure loop in external solve.
virtual const Real & getSideX() const
Return side lengths of the assembly.
virtual const Real & getHeatedLength() const
Return heated length.
Triangular interwrapper solver.
virtual void computeRho(int iblock)
Computes Density per channel for block iblock.
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of inter-wrapper indices for a given gap index.
virtual const Real & getHeatedLengthEntry() const
Return unheated length at entry.
virtual void computeT(int iblock)
Computes Temperature per channel for block iblock.
virtual void computeDP(int iblock) override
computeDP(int iz) is defined/overridden in order to use the friction factor for sodium ...
const TriInterWrapperMesh & _tri_sch_mesh
std::unique_ptr< SolutionHandle > _SumWij_soln
const Real & _P_out
Outlet Pressure.
static InputParameters validParams()
Base class for the 1-phase steady-state/transient interwrapper solver.
const Real & _dt
Time step.
std::unique_ptr< SolutionHandle > _rho_soln
virtual void externalSolve() override
const unsigned int _n_cells
const unsigned int _block_size
std::unique_ptr< SolutionHandle > _mdot_soln
const SinglePhaseFluidProperties * _fp
Solutions handles and link to TH tables properties.
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
std::unique_ptr< SolutionHandle > _T_soln
static const std::string S
static const std::string pitch
const T & getConstMesh(const MooseMesh &mesh)
function to cast const mesh
virtual void computeh(int iblock) override
computeMassFlowForDPDZ() and enforceUniformDPDZAtInlet() are overriden to define the sodium friction ...
TriInterWrapper1PhaseProblem(const InputParameters ¶ms)
const unsigned int _n_channels
std::shared_ptr< AuxiliarySystem > _aux
virtual const std::pair< unsigned int, unsigned int > & getSweepFlowChans(unsigned int i_chan) const
unsigned int _n_blocks
number of axial blocks
const InterWrapperMesh & _subchannel_mesh
std::unique_ptr< SolutionHandle > _DP_soln
const bool _compute_viscosity
Flag that activates or deactivates the calculation of viscosity.
virtual Node * getChannelNode(unsigned int i_chan, unsigned iz) const =0
Get the inter-wrapper mesh node for a given channel index and elevation index.
virtual Real getGapWidth(unsigned int gap_index) const =0
Return gap width for a given gap index.
virtual void computeWijFromSolve(int iblock)
Computes diversion crossflow per gap for block with index iblock Block is a partition of the whole do...
const Real & _T_tol
Convergence tolerance for the temperature loop in external solve.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< SolutionHandle > _q_prime_soln
virtual void initializeSolution()
Function to initialize the solution fields.
virtual void computeMu(int iblock)
Computes Viscosity per channel for block iblock.
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
void mooseError(Args &&... args) const
std::unique_ptr< SolutionHandle > _h_soln
libMesh::DenseMatrix< Real > _Wij_old
const bool _compute_power
Flag that informs if we need to solve the Enthalpy/Temperature equations or not.
const ConsoleStream _console
libMesh::DenseMatrix< Real > & _Wij
bool _converged
Variable that informs whether we exited external solve with a converged solution or not...
libMesh::DenseMatrix< Real > _WijPrime
static InputParameters validParams()
Mesh class for triangular, edge and corner inter_wrappers for hexagonal lattice fuel assemblies...
MooseUnits pow(const MooseUnits &, int)
virtual const Real & getPitch() const
Return the pitch between 2 inter-wrappers.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the inter-wrapper for given inter-wrapper index.
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
virtual const Real & getDuctToPinGap() const
const Real & _CT
Turbulent modeling parameter used in axial momentum equation.
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a signs for the cross flow given a inter-wrapper index and local neighbor index.