diff --git a/include/components/Coaxial1PhaseBase.h b/include/components/Coaxial1PhaseBase.h new file mode 100644 index 0000000..7f5e02f --- /dev/null +++ b/include/components/Coaxial1PhaseBase.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Component.h" +#include "InputParameters.h" + +class Coaxial1PhaseBase : public Component { +public: + Coaxial1PhaseBase(const InputParameters ¶ms) : Component(params) {} + +protected: + // Create constant function based on scalar value + FunctionName CreateFunctionFromValue(const std::string &suffix, + const Real value); + + // Function that copies parameters depending on whether the + // local parameter or global parameter is specified + template + inline void CopyParamFromParamWithGlobal(const std::string dst_name, + const std::string src_name, + const std::string global_src_name, + InputParameters &dst_params); +}; diff --git a/include/components/CoaxialElbow1Phase.h b/include/components/CoaxialElbow1Phase.h new file mode 100644 index 0000000..df1aa25 --- /dev/null +++ b/include/components/CoaxialElbow1Phase.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Coaxial1PhaseBase.h" + +class CoaxialElbow1Phase : public Coaxial1PhaseBase { +public: + static InputParameters validParams(); + + CoaxialElbow1Phase(const InputParameters ¶ms); + +protected: + // Add elbow geometry and form loss for inner pipe + void AddElbowInner(); + + // Add elbow geometry and form loss for outer annulus + void AddElbowOuter(); +}; diff --git a/include/components/CoaxialPipe1Phase.h b/include/components/CoaxialPipe1Phase.h index 97785b8..bd1b644 100644 --- a/include/components/CoaxialPipe1Phase.h +++ b/include/components/CoaxialPipe1Phase.h @@ -1,8 +1,10 @@ -#include +#pragma once + +#include #include #include -class CoaxialPipe1Phase : public Component { +class CoaxialPipe1Phase : public Coaxial1PhaseBase { public: static InputParameters validParams(); @@ -25,8 +27,4 @@ class CoaxialPipe1Phase : public Component { void AddHeatTransferConnection(const std::string &flow_channel, const std::string &hs, const std::string &hs_side, const Real radius); - - // Create constant function based on scalar value - FunctionName CreateFunctionFromValue(const std::string &suffix, - const Real value); }; \ No newline at end of file diff --git a/include/userobjects/ADElbow0D1PhaseUserObject.h b/include/userobjects/ADElbow0D1PhaseUserObject.h new file mode 100644 index 0000000..2340eaf --- /dev/null +++ b/include/userobjects/ADElbow0D1PhaseUserObject.h @@ -0,0 +1,18 @@ +#pragma once + +#include "ADVolumeJunction1PhaseUserObject.h" +#include "InputParameters.h" + +class ADElbow0D1PhaseUserObject : public ADVolumeJunction1PhaseUserObject { +public: + static InputParameters validParams(); + + ADElbow0D1PhaseUserObject(const InputParameters ¶ms); + +protected: + void computeFluxesAndResiduals(const unsigned int &c) override; + + const Real &_r_curv; + + const Real &_d_h; +}; diff --git a/src/components/Coaxial1PhaseBase.C b/src/components/Coaxial1PhaseBase.C new file mode 100644 index 0000000..5420f04 --- /dev/null +++ b/src/components/Coaxial1PhaseBase.C @@ -0,0 +1,25 @@ +#include "Coaxial1PhaseBase.h" + +FunctionName +Coaxial1PhaseBase::CreateFunctionFromValue(const std::string &suffix, + const Real value) { + auto func_params = _factory.getValidParams("ConstantFunction"); + func_params.set("value") = value; + + auto func_name = name() + "_" + suffix; + getTHMProblem().addFunction("ConstantFunction", func_name, func_params); + return func_name; +} + +template +void Coaxial1PhaseBase::CopyParamFromParamWithGlobal( + const std::string dst_name, const std::string src_name, + const std::string global_src_name, InputParameters &dst_params) { + + if (!isParamSetByUser(src_name) && !isParamSetByUser(global_src_name)) + mooseError("Either ", src_name, " or ", global_src_name, " must be set."); + + dst_params.set(dst_name) = (isParamSetByUser(src_name)) + ? getParam(src_name) + : getParam(global_src_name); +} diff --git a/src/components/CoaxialElbow1Phase.C b/src/components/CoaxialElbow1Phase.C new file mode 100644 index 0000000..d96906d --- /dev/null +++ b/src/components/CoaxialElbow1Phase.C @@ -0,0 +1,199 @@ +#include "CoaxialElbow1Phase.h" +#include "CoaxialPipe1Phase.h" +#include "InputParameters.h" +#include "Registry.h" +#include +#include + +registerMooseObject("ProteusApp", CoaxialElbow1Phase); + +namespace { +// Compute momentum loss per unit length using Handbook of Hydraulic Resistance +// p. 195 +Real getElbowKPrime(const Real &R_c, const Real &D_h) { + const Real length = 0.5 * pi * R_c; + Real k; + if (R_c / D_h > 1.) + k = 0.21 / sqrt(R_c / D_h); + else + k = 0.21 / pow(R_c / D_h, 2.5); + + return k / length; +} +} // namespace + +InputParameters CoaxialElbow1Phase::validParams() { + + InputParameters params = CoaxialPipe1Phase::validParams(); + params.addRequiredParam("radius", "Radius of the pipe [m]"); + params.addRequiredParam("start_angle", + "Angle at which the pipe starts [degrees]"); + params.addRequiredParam("end_angle", + "Angle at which the pipe ends [degrees]"); + + // Suppress length. Also need to set it to something, because it is required + // in the parent class + params.set>("length") = {0.0}; + params.suppressParameter>("length"); + + // Momentum losses provided by minor loss formula + params.suppressParameter>("inner_closures"); + params.suppressParameter>("outer_closures"); + params.suppressParameter>("closures"); + // f set to zero + params.suppressParameter("inner_f"); + params.suppressParameter("outer_f"); + params.suppressParameter("f"); + + params.addClassDescription("Bent pipe for 1-phase coaxial flow"); + + return params; +} + +CoaxialElbow1Phase::CoaxialElbow1Phase(const InputParameters ¶ms) + : Coaxial1PhaseBase(params) { + + auto start_angle = getParam("start_angle"); + auto end_angle = getParam("end_angle"); + + // This component is for 90 degree bends + if (!MooseUtils::relativeFuzzyEqual(abs(start_angle - end_angle), 90.)) + mooseError("Difference between start and end angles should be 90 degrees."); + + // Closure has been removed as a parameter to be specified but we must specify + // it + auto closure_params = _factory.getValidParams("Closures1PhaseSimple"); + closure_params.set("_thm_problem") = &getTHMProblem(); + closure_params.set("_logger") = &(getTHMProblem().log()); + getTHMProblem().addClosures("Closures1PhaseSimple", name() + "_closure", + closure_params); + + AddElbowInner(); + AddElbowOuter(); +} + +void CoaxialElbow1Phase::AddElbowInner() { + + const std::string component_name = name() + "/inner"; + Real radius = getParam("tube_inner_radius"); + const Real d_h = 2 * radius; + + // Add elbow geometry for inner pipe and pipe information + { + const std::string class_name = "ElbowPipe1Phase"; + auto pipe_params = _factory.getValidParams(class_name); + pipe_params.set("_thm_problem") = &getTHMProblem(); + + CopyParamFromParamWithGlobal("fp", "inner_fp", "fp", + pipe_params); + + pipe_params.set>("closures") = {name() + + "_closure"}; + pipe_params.set("f") = CreateFunctionFromValue("inner_f", 0.); + + passParameter>("n_elems", pipe_params); + passParameter("position", pipe_params); + passParameter("orientation", pipe_params); + + auto area = pi * radius * radius; + pipe_params.set("A") = + CreateFunctionFromValue("inner_area", area); + + pipe_params.set("D_h") = + CreateFunctionFromValue("inner_dh", d_h); + + CopyParamFromParamWithGlobal("initial_T", "inner_initial_T", + "initial_T", pipe_params); + CopyParamFromParamWithGlobal("initial_p", "inner_initial_p", + "initial_p", pipe_params); + CopyParamFromParamWithGlobal( + "initial_vel", "inner_initial_vel", "initial_vel", pipe_params); + + passParameter("radius", pipe_params); + passParameter("start_angle", pipe_params); + passParameter("end_angle", pipe_params); + + getTHMProblem().addComponent(class_name, component_name, pipe_params); + } + + // Add form loss from Handbook of Hydraulic Resistance p. 195 + { + const std::string class_name = "FormLossFromFunction1Phase"; + auto loss_params = _factory.getValidParams(class_name); + loss_params.set("_thm_problem") = &getTHMProblem(); + loss_params.set("flow_channel") = component_name; + + const Real r_c = getParam("radius"); + + loss_params.set("K_prime") = + CreateFunctionFromValue("inner_k_prime", getElbowKPrime(r_c, d_h)); + + getTHMProblem().addComponent(class_name, component_name + "_loss", + loss_params); + } +} + +void CoaxialElbow1Phase::AddElbowOuter() { + + Real tube_radius = getParam("tube_inner_radius"); + auto tube_widths = getParam>("tube_widths"); + Real inner_radius = + tube_radius + std::accumulate(tube_widths.begin(), tube_widths.end(), 0.); + Real outer_radius = getParam("shell_inner_radius"); + const Real d_h = 2 * (outer_radius - inner_radius); + + // Add elbow geometry for outer annulus + const std::string component_name = name() + "/outer"; + { + const std::string class_name = "ElbowPipe1Phase"; + auto pipe_params = _factory.getValidParams(class_name); + pipe_params.set("_thm_problem") = &getTHMProblem(); + + CopyParamFromParamWithGlobal("fp", "outer_fp", "fp", + pipe_params); + + pipe_params.set>("closures") = {name() + + "_closure"}; + pipe_params.set("f") = CreateFunctionFromValue("outer_f", 0.); + + passParameter>("n_elems", pipe_params); + passParameter("position", pipe_params); + passParameter("orientation", pipe_params); + + auto area = + pi * (outer_radius * outer_radius - inner_radius * inner_radius); + pipe_params.set("A") = + CreateFunctionFromValue("outer_area", area); + + pipe_params.set("D_h") = + CreateFunctionFromValue("outer_dh", d_h); + + CopyParamFromParamWithGlobal("initial_T", "outer_initial_T", + "initial_T", pipe_params); + CopyParamFromParamWithGlobal("initial_p", "outer_initial_p", + "initial_p", pipe_params); + CopyParamFromParamWithGlobal( + "initial_vel", "outer_initial_vel", "initial_vel", pipe_params); + + passParameter("radius", pipe_params); + passParameter("start_angle", pipe_params); + passParameter("end_angle", pipe_params); + + getTHMProblem().addComponent(class_name, component_name, pipe_params); + } + + { + const std::string class_name = "FormLossFromFunction1Phase"; + auto loss_params = _factory.getValidParams(class_name); + loss_params.set("_thm_problem") = &getTHMProblem(); + loss_params.set("flow_channel") = component_name; + + auto r_c = getParam("radius"); + + loss_params.set("K_prime") = + CreateFunctionFromValue("outer_k_prime", getElbowKPrime(r_c, d_h)); + + getTHMProblem().addComponent(class_name, component_name + "_loss", + loss_params); + } +} diff --git a/src/components/CoaxialPipe1Phase.C b/src/components/CoaxialPipe1Phase.C index bf22a5b..789d884 100644 --- a/src/components/CoaxialPipe1Phase.C +++ b/src/components/CoaxialPipe1Phase.C @@ -3,7 +3,6 @@ #include "FEProblemBase.h" #include "Factory.h" #include "InputParameters.h" -#include "MooseError.h" #include "MooseTypes.h" #include "Registry.h" #include "THMProblem.h" @@ -11,25 +10,6 @@ registerMooseObject("ProteusApp", CoaxialPipe1Phase); -namespace { -// Function that copies parameters depending on whether the -// local parameter or global parameter is specified -template -inline void copyParamFromParamWithGlobal(const std::string dst_name, - const std::string src_name, - const std::string global_src_name, - InputParameters &dst_params, - const InputParameters &src_params) { - if (!src_params.isParamSetByUser(src_name) && - !src_params.isParamSetByUser(global_src_name)) - mooseError("Either ", src_name, " or ", global_src_name, " must be set."); - - dst_params.set(dst_name) = (src_params.isParamSetByUser(src_name)) - ? src_params.get(src_name) - : src_params.get(global_src_name); -} -} // namespace - InputParameters CoaxialPipe1Phase::validParams() { // add basic parameters such n_elems, position, etc. InputParameters params = Component1D::validParams(); @@ -52,10 +32,10 @@ InputParameters CoaxialPipe1Phase::validParams() { "Initial inner pipe pressure."); params.addParam("inner_initial_vel", "Initial inner pipe velocity."); - + params.addParam("inner_f", "Friction factor for inner tube."); params.addParamNamesToGroup( "inner_fp inner_closures inner_initial_T inner_initial_p " - "inner_initial_vel", + "inner_initial_vel inner_f", "inner"); // add parameters for the outer annulus @@ -64,14 +44,16 @@ InputParameters CoaxialPipe1Phase::validParams() { params.addParam>( "outer_closures", "Fluid property for outer annulus."); params.addParam("outer_initial_T", - "Initial inner pipe temperature."); + "Initial outer annulus temperature."); params.addParam("outer_initial_p", - "Initial inner pipe pressure."); + "Initial outer annulus pressure."); params.addParam("outer_initial_vel", - "Initial inner pipe velocity."); + "Initial outer annulus velocity."); + params.addParam("outer_f", + "Friction factor for outer annulus."); params.addParamNamesToGroup( "outer_fp outer_closures outer_initial_T outer_initial_p " - "outer_initial_vel", + "outer_initial_vel outer_f", "outer"); // Add parameters for the solid tube @@ -130,14 +112,17 @@ InputParameters CoaxialPipe1Phase::validParams() { params.addParam("initial_p", "Global pressure initialisation"); params.addParam("initial_vel", "Global velocity initialisation"); - params.addParamNamesToGroup("fp closures initial_T initial_p initial_vel", - "global"); + params.addParam( + "gravity_vector", RealVectorValue{0, 0, 9.81}, "gravity vector."); + params.addParam("f", "Global friction factor"); + params.addParamNamesToGroup( + "fp closures initial_T initial_p initial_vel gravity_vector f", "global"); return params; } CoaxialPipe1Phase::CoaxialPipe1Phase(const InputParameters ¶ms) - : Component(params) { + : Coaxial1PhaseBase(params) { // Add components AddInnerPipe(params); AddOuterAnnulus(params); @@ -162,11 +147,11 @@ void CoaxialPipe1Phase::AddInnerPipe(const InputParameters ¶ms) { auto pipe_params = _factory.getValidParams(class_name); pipe_params.set("_thm_problem") = &getTHMProblem(); - copyParamFromParamWithGlobal("fp", "inner_fp", "fp", - pipe_params, params); + CopyParamFromParamWithGlobal("fp", "inner_fp", "fp", + pipe_params); - copyParamFromParamWithGlobal>( - "closures", "inner_closures", "closures", pipe_params, params); + CopyParamFromParamWithGlobal>( + "closures", "inner_closures", "closures", pipe_params); pipe_params.set>("n_elems") = params.get>("n_elems"); @@ -186,12 +171,12 @@ void CoaxialPipe1Phase::AddInnerPipe(const InputParameters ¶ms) { pipe_params.set("D_h") = CreateFunctionFromValue("inner_dh", d_h); - copyParamFromParamWithGlobal("initial_T", "inner_initial_T", - "initial_T", pipe_params, params); - copyParamFromParamWithGlobal("initial_p", "inner_initial_p", - "initial_p", pipe_params, params); - copyParamFromParamWithGlobal( - "initial_vel", "inner_initial_vel", "initial_vel", pipe_params, params); + CopyParamFromParamWithGlobal("initial_T", "inner_initial_T", + "initial_T", pipe_params); + CopyParamFromParamWithGlobal("initial_p", "inner_initial_p", + "initial_p", pipe_params); + CopyParamFromParamWithGlobal("initial_vel", "inner_initial_vel", + "initial_vel", pipe_params); getTHMProblem().addComponent(class_name, name() + "/inner", pipe_params); } @@ -201,11 +186,11 @@ void CoaxialPipe1Phase::AddOuterAnnulus(const InputParameters ¶ms) { auto pipe_params = _factory.getValidParams(class_name); pipe_params.set("_thm_problem") = &getTHMProblem(); - copyParamFromParamWithGlobal("fp", "outer_fp", "fp", - pipe_params, params); + CopyParamFromParamWithGlobal("fp", "outer_fp", "fp", + pipe_params); - copyParamFromParamWithGlobal>( - "closures", "outer_closures", "closures", pipe_params, params); + CopyParamFromParamWithGlobal>( + "closures", "outer_closures", "closures", pipe_params); pipe_params.set>("n_elems") = params.get>("n_elems"); @@ -229,12 +214,12 @@ void CoaxialPipe1Phase::AddOuterAnnulus(const InputParameters ¶ms) { pipe_params.set("D_h") = CreateFunctionFromValue("outer_dh", d_h); - copyParamFromParamWithGlobal("initial_T", "outer_initial_T", - "initial_T", pipe_params, params); - copyParamFromParamWithGlobal("initial_p", "outer_initial_p", - "initial_p", pipe_params, params); - copyParamFromParamWithGlobal( - "initial_vel", "outer_initial_vel", "initial_vel", pipe_params, params); + CopyParamFromParamWithGlobal("initial_T", "outer_initial_T", + "initial_T", pipe_params); + CopyParamFromParamWithGlobal("initial_p", "outer_initial_p", + "initial_p", pipe_params); + CopyParamFromParamWithGlobal("initial_vel", "outer_initial_vel", + "initial_vel", pipe_params); getTHMProblem().addComponent(class_name, name() + "/outer", pipe_params); } @@ -265,8 +250,8 @@ void CoaxialPipe1Phase::AddSolidTube(const InputParameters ¶ms) { tube_params.set>("length") = params.get>("length"); - copyParamFromParamWithGlobal("initial_T", "tube_initial_T", - "initial_T", tube_params, params); + CopyParamFromParamWithGlobal("initial_T", "tube_initial_T", + "initial_T", tube_params); getTHMProblem().addComponent(class_name, name() + "/tube", tube_params); } @@ -298,8 +283,8 @@ void CoaxialPipe1Phase::AddSolidShell(const InputParameters ¶ms) { tube_params.set>("length") = params.get>("length"); - copyParamFromParamWithGlobal("initial_T", "shell_initial_T", - "initial_T", tube_params, params); + CopyParamFromParamWithGlobal("initial_T", "shell_initial_T", + "initial_T", tube_params); getTHMProblem().addComponent(class_name, name() + "/shell", tube_params); } @@ -326,14 +311,3 @@ void CoaxialPipe1Phase::AddHeatTransferConnection( getTHMProblem().addComponent( class_name, name() + "_" + flow_channel + "_" + hs, ht_params); } - -FunctionName -CoaxialPipe1Phase::CreateFunctionFromValue(const std::string &suffix, - const Real value) { - auto func_params = _factory.getValidParams("ConstantFunction"); - func_params.set("value") = value; - - auto func_name = name() + "_" + suffix; - getTHMProblem().addFunction("ConstantFunction", func_name, func_params); - return func_name; -} \ No newline at end of file diff --git a/src/userobjects/Elbow0D1PhaseUserObject.C b/src/userobjects/Elbow0D1PhaseUserObject.C new file mode 100644 index 0000000..e542fff --- /dev/null +++ b/src/userobjects/Elbow0D1PhaseUserObject.C @@ -0,0 +1 @@ +#include "ADElbow0D1PhaseUserObject.h" diff --git a/test/tests/components/coaxial_elbow/elbow_test.i b/test/tests/components/coaxial_elbow/elbow_test.i new file mode 100644 index 0000000..70713be --- /dev/null +++ b/test/tests/components/coaxial_elbow/elbow_test.i @@ -0,0 +1,181 @@ +# Elbow pressure drop tests +# =================== +# +# Check pressure drop matches correlations + +T_in = ${fparse 50 + 273.15} # Arbitrary reference temperature +mdot = 0.5 # nominal mass flow rate for primary +press = 1e5 # operating pressure + + +[GlobalParams] + initial_p = ${press} + initial_T = ${T_in} + fp=fluid + gravity_vector = '0 0 0' +[] + +[FluidProperties] + [fluid] # mimic of water + type = SimpleFluidProperties + [] +[] + +[SolidProperties] # Not currently needed as solid heat transfer not considered yet + [adamantium] # fake solid material that ensures solid heats quickly + type = ThermalFunctionSolidProperties + cp = 40 + k = 50 + rho = 100 + [] +[] + +[Closures] # defines friction factors and heat transfer coefficients + [thm_closures] + type = Closures1PhaseTHM # default Churchill friction factor, DB HTC + [] +[] + +[Components] + [inlet_inner] + type = InletMassFlowRateTemperature1Phase + T = ${T_in} + m_dot = ${mdot} + input = coaxial/inner:in + [] + [inlet_outer] + type = InletMassFlowRateTemperature1Phase + T = ${T_in} + m_dot = ${mdot} + input = coaxial/outer:in + [] + [coaxial] + type = CoaxialElbow1Phase + n_elems = 200 + orientation = '1 0 0' + start_angle = 0. + radius = 0.1 + end_angle = 90 + position = '0 0 0' + shell_inner_radius = 0.075 + shell_materials = 'adamantium' + shell_n_elems = '10' + shell_names = 'shell' + shell_widths = '0.025' + shell_T_ref = '${T_in}' + tube_T_ref = ${T_in} + tube_inner_radius = 0.025 + tube_materials = 'adamantium' + tube_n_elems = '10' + tube_names = 'tube' + tube_widths = '0.025' + inner_initial_vel = 0.02 + outer_initial_vel = 0.05 + [] + [outlet_outer] + type =Outlet1Phase + input = coaxial/outer:out + p = ${press} + [] + [outlet_inner] + type =Outlet1Phase + input = coaxial/inner:out + p = ${press} + [] +[] + + +[Postprocessors] + [p_inlet_inner] + type = SideAverageValue + boundary = coaxial/inner:in + variable = p + [] + [p_outlet_inner] + type = SideAverageValue + boundary = coaxial/inner:out + variable = p + [] + [p_inlet_outer] + type = SideAverageValue + boundary = coaxial/outer:in + variable = p + [] + [p_outlet_outer] + type = SideAverageValue + boundary = coaxial/outer:out + variable = p + [] + [vel_inlet_inner] + type = SideAverageValue + boundary = coaxial/inner:in + variable = vel_y + [] + [vel_inlet_outer] + type = SideAverageValue + boundary = coaxial/outer:in + variable = vel_y + [] + [rho_inner] + type = ADSideAverageMaterialProperty + boundary = coaxial/inner:out + property = rho + [] + [rho_outer] + type = ADSideAverageMaterialProperty + boundary = coaxial/outer:out + property = rho + [] + [delta_p_inner] + type = ParsedPostprocessor + expression = 'p_out - p_in' + pp_names = 'p_outlet_inner p_inlet_inner' + pp_symbols = 'p_in p_out' + [] + [delta_p_outer] + type = ParsedPostprocessor + expression = 'p_out - p_in' + pp_names = 'p_outlet_outer p_inlet_outer' + pp_symbols = 'p_in p_out' + [] +[] + +[Preconditioning] + [pc] + type = SMP + full = true + [] +[] + +[Executioner] + type = Transient + start_time = 0 + + dt = 0.025 + end_time = 2000 + + line_search = basic + solve_type = NEWTON + + petsc_options_iname = '-pc_type' + petsc_options_value = 'lu' + + nl_rel_tol = 1e-3 + nl_abs_tol = 1e-6 + nl_max_its = 25 + automatic_scaling = true + steady_state_detection = true + steady_state_tolerance = 5e-7 +[] + +[Outputs] + exodus = true + csv = true + [console] + type = Console + max_rows = 1 + execute_postprocessors_on = final + outlier_variable_norms = false + [] + print_linear_residuals = false +[] diff --git a/test/tests/components/coaxial_elbow/test.py b/test/tests/components/coaxial_elbow/test.py new file mode 100644 index 0000000..87be41d --- /dev/null +++ b/test/tests/components/coaxial_elbow/test.py @@ -0,0 +1,44 @@ +"""Python test module for coaxial elbows.""" + +import unittest + +import numpy as np + + +class TestCoaxialElbow(unittest.TestCase): + """Test class for the coaxial elbow component.""" + + def test_inner_pressure_loss(self): + """Compares pressure drop with expected value for inner pipe.""" + r_c = 0.1 + + delta_p_inner, rho, vel_inlet = np.loadtxt("elbow_test_out.csv", + delimiter=',', + skiprows=1, + usecols=(1, 7, 9), + unpack=True)[:,-1] + k = 0.21/np.sqrt(r_c/0.05) + expected = k* 0.5*rho*vel_inlet*vel_inlet + + diff = abs((expected - delta_p_inner)/expected) + assert diff < 5e-3, ( + f"Inner pressure loss wrong {expected} vs {delta_p_inner}. Diff {diff}" + ) + + def test_outer_pressure_loss(self): + """Compares pressure drop with expected value for outer annulus.""" + + r_c = 0.1 + + delta_p_inner, rho, vel_inlet = np.loadtxt("elbow_test_out.csv", + delimiter=',', + skiprows=1, + usecols=(2, 8, 10), + unpack=True)[:,-1] + k = 0.21/np.sqrt(r_c/0.05) + expected = k* 0.5*rho*vel_inlet*vel_inlet + + diff = abs((expected - delta_p_inner)/expected) + assert diff < 5e-3, ( + f"Outer pressure loss wrong {expected} vs {delta_p_inner}. Diff {diff}" + ) diff --git a/test/tests/components/coaxial_elbow/tests b/test/tests/components/coaxial_elbow/tests new file mode 100644 index 0000000..b983bd8 --- /dev/null +++ b/test/tests/components/coaxial_elbow/tests @@ -0,0 +1,22 @@ +[Tests] + [coaxial_elbow] + [run] + type = RunApp + input = elbow_test.i + requirement = 'This system shall permit a valid elbow component to run.' + [] + [verify] + type = PythonUnitTest + input = test.py + prereq = coaxial_elbow/run + requirement = 'This system shall calculate pressure drops corresponding with empirical correlations' + [] + [angle_check] + type = RunException + input = elbow_test.i + cli_args = 'Components/coaxial/end_angle=100' + expect_err = 'Difference between start and end angles should be 90 degrees' + requirement = 'This system shall only permit elbow angles of 90 degrees' + [] + [] +[] diff --git a/test/tests/components/coaxial_pipe/test.py b/test/tests/components/coaxial_pipe/test.py index 65ba671..c21470a 100644 --- a/test/tests/components/coaxial_pipe/test.py +++ b/test/tests/components/coaxial_pipe/test.py @@ -9,9 +9,9 @@ def test_energy_balance(self): """Compares energy increase in pipes to heat flux input on shell exterior.""" _, t_inner, t_outer, q = np.loadtxt("energy_balance_out.csv", - skiprows=2, - delimiter=',', - unpack=True)[:,-1] + skiprows=2, + delimiter=',', + unpack=True)[:,-1] # mass flow rate in pipe and annulus 0.1 kg/s m_dot = 0.1