https://mooseframework.inl.gov
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
TriSubChannel1PhaseProblem Class Referenceabstract

Triangular subchannel solver. More...

#include <TriSubChannel1PhaseProblem.h>

Inheritance diagram for TriSubChannel1PhaseProblem:
[legend]

Public Types

enum  Direction { Direction::TO_EXTERNAL_APP, Direction::FROM_EXTERNAL_APP }
 
enum  CoverageCheckMode {
  CoverageCheckMode::FALSE, CoverageCheckMode::TRUE, CoverageCheckMode::OFF, CoverageCheckMode::ON,
  CoverageCheckMode::SKIP_LIST, CoverageCheckMode::ONLY_LIST
}
 
typedef DataFileName DataFileParameterType
 

Public Member Functions

 TriSubChannel1PhaseProblem (const InputParameters &params)
 
virtual ~TriSubChannel1PhaseProblem ()
 
virtual void externalSolve () override
 
virtual void syncSolutions (Direction direction) override
 
virtual bool solverSystemConverged (const unsigned int) override
 
virtual void initialSetup () override
 
const SCMHTCClosureBasegetDuctHTCClosure () const
 
const SCMHTCClosureBasegetPinHTCClosure () const
 
const SCMFrictionClosureBasegetFrictionClosure () const
 
Real getAddedHeatPin (unsigned int i_ch, unsigned int iz) const
 Return the added heat coming from the fuel pins. More...
 
Real getAddedHeatDuct (unsigned int i_ch, unsigned int iz) const
 Return the added heat coming from the duct. More...
 
const PostprocessorValuegetOutletPressure () const
 Get outlet pressure. More...
 
const SinglePhaseFluidPropertiesgetSinglePhaseFluidProperties () const
 Get fluid properties object. More...
 
virtual void solve (unsigned int nl_sys_num=0) override final
 
virtual void addExternalVariables ()
 
bool initialized () const
 
virtual libMesh::EquationSystemses () override
 
virtual MooseMeshmesh () override
 
virtual const MooseMeshmesh () const override
 
const MooseMeshmesh (bool use_displaced) const override
 
MooseMeshmesh (bool use_displaced)
 
void setCoordSystem (const std::vector< SubdomainName > &blocks, const MultiMooseEnum &coord_sys)
 
void setAxisymmetricCoordAxis (const MooseEnum &rz_coord_axis)
 
void setCoupling (Moose::CouplingType type)
 
Moose::CouplingType coupling () const
 
void setCouplingMatrix (std::unique_ptr< libMesh::CouplingMatrix > cm, const unsigned int nl_sys_num)
 
void setCouplingMatrix (libMesh::CouplingMatrix *cm, const unsigned int nl_sys_num)
 
const libMesh::CouplingMatrixcouplingMatrix (const unsigned int nl_sys_num) const override
 
void setNonlocalCouplingMatrix ()
 
bool areCoupled (const unsigned int ivar, const unsigned int jvar, const unsigned int nl_sys_num) const
 
bool hasUOAuxStateCheck () const
 
bool checkingUOAuxState () const
 
virtual bool checkResidualForNans () const override
 
void setCheckResidualForNans (bool check_residual_for_nans)
 
void trustUserCouplingMatrix ()
 
std::vector< std::pair< MooseVariableFieldBase *, MooseVariableFieldBase *> > & couplingEntries (const THREAD_ID tid, const unsigned int nl_sys_num)
 
std::vector< std::pair< MooseVariableFieldBase *, MooseVariableFieldBase *> > & nonlocalCouplingEntries (const THREAD_ID tid, const unsigned int nl_sys_num)
 
virtual bool hasVariable (const std::string &var_name) const override
 
bool hasSolverVariable (const std::string &var_name) const
 
virtual const MooseVariableFieldBasegetVariable (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
 
virtual const MooseVariableFieldBasegetVariable (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const =0
 
virtual MooseVariableFieldBasegetVariable (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY)
 
virtual MooseVariableFieldBasegetVariable (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY)
 
MooseVariableFieldBasegetActualFieldVariable (const THREAD_ID tid, const std::string &var_name) override
 
virtual MooseVariablegetStandardVariable (const THREAD_ID tid, const std::string &var_name) override
 
virtual VectorMooseVariablegetVectorVariable (const THREAD_ID tid, const std::string &var_name) override
 
virtual ArrayMooseVariablegetArrayVariable (const THREAD_ID tid, const std::string &var_name) override
 
virtual bool hasScalarVariable (const std::string &var_name) const override
 
virtual MooseVariableScalargetScalarVariable (const THREAD_ID tid, const std::string &var_name) override
 
virtual libMesh::SystemgetSystem (const std::string &var_name) override
 
const RestartableEquationSystemsgetRestartableEquationSystems () const
 
virtual void setActiveElementalMooseVariables (const std::set< MooseVariableFEBase * > &moose_vars, const THREAD_ID tid) override
 
virtual void clearActiveElementalMooseVariables (const THREAD_ID tid) override
 
virtual void clearActiveFEVariableCoupleableMatrixTags (const THREAD_ID tid) override
 
virtual void clearActiveFEVariableCoupleableVectorTags (const THREAD_ID tid) override
 
virtual void setActiveFEVariableCoupleableVectorTags (std::set< TagID > &vtags, const THREAD_ID tid) override
 
virtual void setActiveFEVariableCoupleableMatrixTags (std::set< TagID > &mtags, const THREAD_ID tid) override
 
virtual void clearActiveScalarVariableCoupleableMatrixTags (const THREAD_ID tid) override
 
virtual void clearActiveScalarVariableCoupleableVectorTags (const THREAD_ID tid) override
 
virtual void setActiveScalarVariableCoupleableVectorTags (std::set< TagID > &vtags, const THREAD_ID tid) override
 
virtual void setActiveScalarVariableCoupleableMatrixTags (std::set< TagID > &mtags, const THREAD_ID tid) override
 
virtual void createQRules (libMesh::QuadratureType type, libMesh::Order order, libMesh::Order volume_order=libMesh::INVALID_ORDER, libMesh::Order face_order=libMesh::INVALID_ORDER, SubdomainID block=Moose::ANY_BLOCK_ID, bool allow_negative_qweights=true)
 
void bumpVolumeQRuleOrder (libMesh::Order order, SubdomainID block)
 
void bumpAllQRuleOrder (libMesh::Order order, SubdomainID block)
 
unsigned int getMaxQps () const
 
libMesh::Order getMaxScalarOrder () const
 
void checkNonlocalCoupling ()
 
void checkUserObjectJacobianRequirement (THREAD_ID tid)
 
void setVariableAllDoFMap (const std::vector< const MooseVariableFEBase * > &moose_vars)
 
const std::vector< const MooseVariableFEBase *> & getUserObjectJacobianVariables (const THREAD_ID tid) const
 
virtual Assemblyassembly (const THREAD_ID tid, const unsigned int sys_num) override
 
virtual const Assemblyassembly (const THREAD_ID tid, const unsigned int sys_num) const override
 
Moose::Kokkos::AssemblykokkosAssembly ()
 
const Moose::Kokkos::AssemblykokkosAssembly () const
 
virtual std::vector< VariableName > getVariableNames ()
 
void checkDuplicatePostprocessorVariableNames ()
 
void timestepSetup () override
 
void customSetup (const ExecFlagType &exec_type) override
 
void residualSetup () override
 
void jacobianSetup () override
 
virtual void prepare (const Elem *elem, const THREAD_ID tid) override
 
virtual void prepare (const Elem *elem, unsigned int ivar, unsigned int jvar, const std::vector< dof_id_type > &dof_indices, const THREAD_ID tid) override
 
virtual void prepareFace (const Elem *elem, const THREAD_ID tid) override
 
virtual void setCurrentSubdomainID (const Elem *elem, const THREAD_ID tid) override
 
virtual void setNeighborSubdomainID (const Elem *elem, unsigned int side, const THREAD_ID tid) override
 
virtual void setNeighborSubdomainID (const Elem *elem, const THREAD_ID tid)
 
virtual void prepareAssembly (const THREAD_ID tid) override
 
virtual void prepareAssemblyNeighbor (const THREAD_ID tid)
 
virtual void addGhostedElem (dof_id_type elem_id) override
 
virtual void addGhostedBoundary (BoundaryID boundary_id) override
 
virtual void ghostGhostedBoundaries () override
 
virtual void sizeZeroes (unsigned int size, const THREAD_ID tid)
 
virtual bool reinitDirac (const Elem *elem, const THREAD_ID tid) override
 
virtual void reinitElem (const Elem *elem, const THREAD_ID tid) override
 
virtual void reinitElemPhys (const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid) override
 
void reinitElemFace (const Elem *elem, unsigned int side, BoundaryID, const THREAD_ID tid)
 
virtual void reinitElemFace (const Elem *elem, unsigned int side, const THREAD_ID tid) override
 
virtual void reinitLowerDElem (const Elem *lower_d_elem, const THREAD_ID tid, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
 
virtual void reinitNode (const Node *node, const THREAD_ID tid) override
 
virtual void reinitNodeFace (const Node *node, BoundaryID bnd_id, const THREAD_ID tid) override
 
virtual void reinitNodes (const std::vector< dof_id_type > &nodes, const THREAD_ID tid) override
 
virtual void reinitNodesNeighbor (const std::vector< dof_id_type > &nodes, const THREAD_ID tid) override
 
virtual void reinitNeighbor (const Elem *elem, unsigned int side, const THREAD_ID tid) override
 
virtual void reinitNeighborPhys (const Elem *neighbor, unsigned int neighbor_side, const std::vector< Point > &physical_points, const THREAD_ID tid) override
 
virtual void reinitNeighborPhys (const Elem *neighbor, const std::vector< Point > &physical_points, const THREAD_ID tid) override
 
virtual void reinitElemNeighborAndLowerD (const Elem *elem, unsigned int side, const THREAD_ID tid) override
 
virtual void reinitScalars (const THREAD_ID tid, bool reinit_for_derivative_reordering=false) override
 
virtual void reinitOffDiagScalars (const THREAD_ID tid) override
 
virtual void getDiracElements (std::set< const Elem * > &elems) override
 
virtual void clearDiracInfo () override
 
virtual void subdomainSetup (SubdomainID subdomain, const THREAD_ID tid)
 
virtual void neighborSubdomainSetup (SubdomainID subdomain, const THREAD_ID tid)
 
virtual void newAssemblyArray (std::vector< std::shared_ptr< SolverSystem >> &solver_systems)
 
virtual void initNullSpaceVectors (const InputParameters &parameters, std::vector< std::shared_ptr< NonlinearSystemBase >> &nl)
 
virtual void init () override
 
void initKokkos ()
 
virtual void solveLinearSystem (const unsigned int linear_sys_num, const Moose::PetscSupport::PetscOptions *po=nullptr)
 
virtual void setException (const std::string &message)
 
virtual bool hasException ()
 
virtual void checkExceptionAndStopSolve (bool print_message=true)
 
virtual unsigned int nNonlinearIterations (const unsigned int nl_sys_num) const override
 
virtual unsigned int nLinearIterations (const unsigned int nl_sys_num) const override
 
virtual Real finalNonlinearResidual (const unsigned int nl_sys_num) const override
 
virtual bool computingPreSMOResidual (const unsigned int nl_sys_num) const override
 
virtual std::string solverTypeString (unsigned int solver_sys_num=0)
 
virtual bool startedInitialSetup ()
 
virtual void onTimestepBegin () override
 
virtual void onTimestepEnd () override
 
virtual Realtime () const
 
virtual RealtimeOld () const
 
virtual inttimeStep () const
 
virtual Realdt () const
 
virtual RealdtOld () const
 
Real getTimeFromStateArg (const Moose::StateArg &state) const
 
virtual void transient (bool trans)
 
virtual bool isTransient () const override
 
virtual void addTimeIntegrator (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual void addPredictor (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual void copySolutionsBackwards ()
 
void skipNextForwardSolutionCopyToOld ()
 
virtual void advanceState ()
 
virtual void restoreSolutions ()
 
virtual void saveOldSolutions ()
 
virtual void restoreOldSolutions ()
 
void needSolutionState (unsigned int oldest_needed, Moose::SolutionIterationType iteration_type)
 
bool hasSolutionState (unsigned int state, Moose::SolutionIterationType iteration_type) const
 
virtual void outputStep (ExecFlagType type)
 
virtual void postExecute ()
 
void forceOutput ()
 
virtual void initPetscOutputAndSomeSolverSettings ()
 
Moose::PetscSupport::PetscOptionsgetPetscOptions ()
 
void logAdd (const std::string &system, const std::string &name, const std::string &type, const InputParameters &params) const
 
virtual void addFunction (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual bool hasFunction (const std::string &name, const THREAD_ID tid=0)
 
virtual FunctiongetFunction (const std::string &name, const THREAD_ID tid=0)
 
virtual void addKokkosFunction (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual bool hasKokkosFunction (const std::string &name) const
 
virtual Moose::Kokkos::Function getKokkosFunction (const std::string &name)
 
TgetKokkosFunction (const std::string &name)
 
virtual void addMeshDivision (const std::string &type, const std::string &name, InputParameters &params)
 
MeshDivisiongetMeshDivision (const std::string &name, const THREAD_ID tid=0) const
 
virtual void addConvergence (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual ConvergencegetConvergence (const std::string &name, const THREAD_ID tid=0) const
 
virtual const std::vector< std::shared_ptr< Convergence > > & getConvergenceObjects (const THREAD_ID tid=0) const
 
virtual bool hasConvergence (const std::string &name, const THREAD_ID tid=0) const
 
bool needToAddDefaultNonlinearConvergence () const
 
bool needToAddDefaultMultiAppFixedPointConvergence () const
 
bool needToAddDefaultSteadyStateConvergence () const
 
void setNeedToAddDefaultNonlinearConvergence ()
 
void setNeedToAddDefaultMultiAppFixedPointConvergence ()
 
void setNeedToAddDefaultSteadyStateConvergence ()
 
bool hasSetMultiAppFixedPointConvergenceName () const
 
bool hasSetSteadyStateConvergenceName () const
 
virtual void addDefaultNonlinearConvergence (const InputParameters &params)
 
virtual bool onlyAllowDefaultNonlinearConvergence () const
 
void addDefaultMultiAppFixedPointConvergence (const InputParameters &params)
 
void addDefaultSteadyStateConvergence (const InputParameters &params)
 
virtual void addLineSearch (const InputParameters &)
 
virtual void lineSearch ()
 
LineSearchgetLineSearch () override
 
virtual void addDistribution (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual bool hasDistribution (const std::string &name) const
 
virtual DistributiongetDistribution (const std::string &name)
 
virtual void addSampler (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual SamplergetSampler (const std::string &name, const THREAD_ID tid=0)
 
NonlinearSystemBasegetNonlinearSystemBase (const unsigned int sys_num)
 
const NonlinearSystemBasegetNonlinearSystemBase (const unsigned int sys_num) const
 
void setCurrentNonlinearSystem (const unsigned int nl_sys_num)
 
NonlinearSystemBasecurrentNonlinearSystem ()
 
const NonlinearSystemBasecurrentNonlinearSystem () const
 
virtual const SystemBasesystemBaseNonlinear (const unsigned int sys_num) const override
 
virtual SystemBasesystemBaseNonlinear (const unsigned int sys_num) override
 
virtual const SystemBasesystemBaseSolver (const unsigned int sys_num) const override
 
virtual SystemBasesystemBaseSolver (const unsigned int sys_num) override
 
virtual const SystemBasesystemBaseAuxiliary () const override
 
virtual SystemBasesystemBaseAuxiliary () override
 
virtual NonlinearSystemgetNonlinearSystem (const unsigned int sys_num)
 
virtual const SystemBasegetSystemBase (const unsigned int sys_num) const
 
virtual SystemBasegetSystemBase (const unsigned int sys_num)
 
SystemBasegetSystemBase (const std::string &sys_name)
 
LinearSystemgetLinearSystem (unsigned int sys_num)
 
const LinearSystemgetLinearSystem (unsigned int sys_num) const
 
SolverSystemgetSolverSystem (unsigned int sys_num)
 
const SolverSystemgetSolverSystem (unsigned int sys_num) const
 
void setCurrentLinearSystem (unsigned int sys_num)
 
LinearSystemcurrentLinearSystem ()
 
const LinearSystemcurrentLinearSystem () const
 
virtual const SystemBasesystemBaseLinear (unsigned int sys_num) const override
 
virtual SystemBasesystemBaseLinear (unsigned int sys_num) override
 
virtual void addVariable (const std::string &var_type, const std::string &var_name, InputParameters &params)
 
virtual void addKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addHDGKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addNodalKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addScalarKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addBoundaryCondition (const std::string &bc_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosNodalKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosBoundaryCondition (const std::string &bc_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosLinearFVKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosLinearFVBC (const std::string &bc_name, const std::string &name, InputParameters &parameters)
 
virtual void addConstraint (const std::string &c_name, const std::string &name, InputParameters &parameters)
 
virtual void setInputParametersFEProblem (InputParameters &parameters)
 
virtual void addAuxVariable (const std::string &var_type, const std::string &var_name, InputParameters &params)
 
virtual void addAuxVariable (const std::string &var_name, const libMesh::FEType &type, const std::set< SubdomainID > *const active_subdomains=NULL)
 
virtual void addElementalFieldVariable (const std::string &var_type, const std::string &var_name, InputParameters &params)
 
virtual void addAuxArrayVariable (const std::string &var_name, const libMesh::FEType &type, unsigned int components, const std::set< SubdomainID > *const active_subdomains=NULL)
 
virtual void addAuxScalarVariable (const std::string &var_name, libMesh::Order order, Real scale_factor=1., const std::set< SubdomainID > *const active_subdomains=NULL)
 
virtual void addAuxKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addAuxScalarKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosAuxKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
AuxiliarySystemgetAuxiliarySystem ()
 
virtual void addDiracKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addDGKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addFVKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addLinearFVKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addFVBC (const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
 
virtual void addLinearFVBC (const std::string &fv_bc_name, const std::string &name, InputParameters &parameters)
 
virtual void addFVInterfaceKernel (const std::string &fv_ik_name, const std::string &name, InputParameters &parameters)
 
virtual void addInterfaceKernel (const std::string &kernel_name, const std::string &name, InputParameters &parameters)
 
virtual void addInitialCondition (const std::string &ic_name, const std::string &name, InputParameters &parameters)
 
virtual void addFVInitialCondition (const std::string &ic_name, const std::string &name, InputParameters &parameters)
 
void projectSolution ()
 
unsigned short getCurrentICState ()
 
void projectInitialConditionOnCustomRange (libMesh::ConstElemRange &elem_range, ConstBndNodeRange &bnd_node_range, const std::optional< std::set< VariableName >> &target_vars=std::nullopt)
 
void projectFunctionOnCustomRange (ConstElemRange &elem_range, Number(*func)(const Point &, const libMesh::Parameters &, const std::string &, const std::string &), Gradient(*func_grad)(const Point &, const libMesh::Parameters &, const std::string &, const std::string &), const libMesh::Parameters &params, const std::vector< VariableName > &target_vars)
 
virtual void addMaterial (const std::string &material_name, const std::string &name, InputParameters &parameters)
 
virtual void addMaterialHelper (std::vector< MaterialWarehouse * > warehouse, const std::string &material_name, const std::string &name, InputParameters &parameters)
 
virtual void addInterfaceMaterial (const std::string &material_name, const std::string &name, InputParameters &parameters)
 
virtual void addFunctorMaterial (const std::string &functor_material_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosMaterial (const std::string &material_name, const std::string &name, InputParameters &parameters)
 
void prepareMaterials (const std::unordered_set< unsigned int > &consumer_needed_mat_props, const SubdomainID blk_id, const THREAD_ID tid)
 
void reinitMaterials (SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true)
 
void reinitMaterialsFace (SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase * > *reinit_mats=nullptr)
 
void reinitMaterialsFaceOnBoundary (const BoundaryID boundary_id, const SubdomainID blk_id, const THREAD_ID tid, const bool swap_stateful=true, const std::deque< MaterialBase * > *const reinit_mats=nullptr)
 
void reinitMaterialsNeighborOnBoundary (const BoundaryID boundary_id, const SubdomainID blk_id, const THREAD_ID tid, const bool swap_stateful=true, const std::deque< MaterialBase * > *const reinit_mats=nullptr)
 
void reinitMaterialsNeighbor (SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase * > *reinit_mats=nullptr)
 
void reinitMaterialsBoundary (BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase * > *reinit_mats=nullptr)
 
void reinitMaterialsInterface (BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true)
 
void prepareKokkosMaterials (const std::unordered_set< unsigned int > &consumer_needed_mat_props)
 
void reinitKokkosMaterials ()
 
virtual void swapBackMaterials (const THREAD_ID tid)
 
virtual void swapBackMaterialsFace (const THREAD_ID tid)
 
virtual void swapBackMaterialsNeighbor (const THREAD_ID tid)
 
void setActiveMaterialProperties (const std::unordered_set< unsigned int > &mat_prop_ids, const THREAD_ID tid)
 
bool hasActiveMaterialProperties (const THREAD_ID tid) const
 
void clearActiveMaterialProperties (const THREAD_ID tid)
 
std::vector< std::shared_ptr< T > > addObject (const std::string &type, const std::string &name, InputParameters &parameters, const bool threaded=true, const std::string &var_param_name="variable")
 
virtual void addPostprocessor (const std::string &pp_name, const std::string &name, InputParameters &parameters)
 
virtual void addVectorPostprocessor (const std::string &pp_name, const std::string &name, InputParameters &parameters)
 
virtual void addReporter (const std::string &type, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosPostprocessor (const std::string &pp_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosVectorPostprocessor (const std::string &pp_name, const std::string &name, InputParameters &parameters)
 
virtual void addKokkosReporter (const std::string &type, const std::string &name, InputParameters &parameters)
 
const ReporterDatagetReporterData () const
 
ReporterDatagetReporterData (ReporterData::WriteKey)
 
virtual std::vector< std::shared_ptr< UserObject > > addUserObject (const std::string &user_object_name, const std::string &name, InputParameters &parameters)
 
TgetUserObject (const std::string &name, unsigned int tid=0) const
 
const UserObjectgetUserObjectBase (const std::string &name, const THREAD_ID tid=0) const
 
bool hasUserObject (const std::string &name) const
 
virtual void addKokkosUserObject (const std::string &user_object_name, const std::string &name, InputParameters &parameters)
 
const TgetKokkosUserObject (const std::string &name) const
 
bool hasKokkosUserObject (const std::string &name) const
 
void checkUserObjectNameCollision (const std::string &name, const std::string &type) const
 
const PositionsgetPositionsObject (const std::string &name) const
 
virtual void addFVInterpolationMethod (const std::string &method_type, const std::string &name, InputParameters &parameters)
 
const FVInterpolationMethodgetFVInterpolationMethod (const InterpolationMethodName &name, const THREAD_ID tid=0) const
 
const FVFaceInterpolationMethodgetFVFaceInterpolationMethod (const InterpolationMethodName &name, const THREAD_ID tid=0) const
 
const FVAdvectedInterpolationMethodgetFVAdvectedInterpolationMethod (const InterpolationMethodName &name, const THREAD_ID tid=0) const
 
bool hasFVInterpolationMethod (const InterpolationMethodName &name) const
 
bool hasPostprocessorValueByName (const PostprocessorName &name) const
 
const PostprocessorgetPostprocessorObjectByName (const PostprocessorName &object_name, const THREAD_ID tid=0) const
 
const PostprocessorValuegetPostprocessorValueByName (const PostprocessorName &name, std::size_t t_index=0) const
 
virtual const PostprocessorValuegetPostprocessorValueByName (const PostprocessorName &name) const
 
void setPostprocessorValueByName (const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
 
bool hasPostprocessor (const std::string &name) const
 
bool hasPostprocessor (const std::string &param_name, const unsigned int index=0) const
 
const VectorPostprocessorValuegetVectorPostprocessorValueByName (const std::string &object_name, const std::string &vector_name, std::size_t t_index=0) const
 
void setVectorPostprocessorValueByName (const std::string &object_name, const std::string &vector_name, const VectorPostprocessorValue &value, std::size_t t_index=0)
 
const VectorPostprocessorgetVectorPostprocessorObjectByName (const std::string &object_name, const THREAD_ID tid=0) const
 
virtual void addDamper (const std::string &damper_name, const std::string &name, InputParameters &parameters)
 
void setupDampers ()
 
bool hasDampers ()
 
virtual void addIndicator (const std::string &indicator_name, const std::string &name, InputParameters &parameters)
 
virtual void addMarker (const std::string &marker_name, const std::string &name, InputParameters &parameters)
 
virtual void addMultiApp (const std::string &multi_app_name, const std::string &name, InputParameters &parameters)
 
std::shared_ptr< MultiAppgetMultiApp (const std::string &multi_app_name) const
 
std::vector< std::shared_ptr< Transfer > > getTransfers (ExecFlagType type, Transfer::DIRECTION direction) const
 
std::vector< std::shared_ptr< Transfer > > getTransfers (Transfer::DIRECTION direction) const
 
const ExecuteMooseObjectWarehouse< Transfer > & getMultiAppTransferWarehouse (Transfer::DIRECTION direction) const
 
void execMultiAppTransfers (ExecFlagType type, Transfer::DIRECTION direction)
 
bool execMultiApps (ExecFlagType type, bool auto_advance=true)
 
void finalizeMultiApps ()
 
void incrementMultiAppTStep (ExecFlagType type)
 
void advanceMultiApps (ExecFlagType type)
 
void finishMultiAppStep (ExecFlagType type, bool recurse_through_multiapp_levels=false)
 
void backupMultiApps (ExecFlagType type)
 
void restoreMultiApps (ExecFlagType type, bool force=false)
 
Real computeMultiAppsDT (ExecFlagType type)
 
virtual void addTransfer (const std::string &transfer_name, const std::string &name, InputParameters &parameters)
 
void execTransfers (ExecFlagType type)
 
Real computeResidualL2Norm (NonlinearSystemBase &sys)
 
Real computeResidualL2Norm (LinearSystem &sys)
 
virtual Real computeResidualL2Norm ()
 
virtual void computeResidualSys (libMesh::NonlinearImplicitSystem &sys, const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual)
 
void computeResidual (libMesh::NonlinearImplicitSystem &sys, const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual)
 
virtual void computeResidual (const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, const unsigned int nl_sys_num)
 
void computeResidualAndJacobian (const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, libMesh::SparseMatrix< libMesh::Number > &jacobian)
 
virtual void computeResidualTag (const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, TagID tag)
 
virtual void computeResidualType (const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, TagID tag)
 
virtual void computeResidualInternal (const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, const std::set< TagID > &tags)
 
virtual void computeResidualTags (const std::set< TagID > &tags)
 
virtual void computeJacobianSys (libMesh::NonlinearImplicitSystem &sys, const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian)
 
virtual void computeJacobian (const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, const unsigned int nl_sys_num)
 
virtual void computeJacobianTag (const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, TagID tag)
 
virtual void computeJacobianInternal (const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, const std::set< TagID > &tags)
 
virtual void computeJacobianTags (const std::set< TagID > &tags)
 
virtual void computeJacobianBlocks (std::vector< JacobianBlock * > &blocks, const unsigned int nl_sys_num)
 
virtual void computeJacobianBlock (libMesh::SparseMatrix< libMesh::Number > &jacobian, libMesh::System &precond_system, unsigned int ivar, unsigned int jvar)
 
virtual void computeLinearSystemSys (libMesh::LinearImplicitSystem &sys, libMesh::SparseMatrix< libMesh::Number > &system_matrix, NumericVector< libMesh::Number > &rhs, const bool compute_gradients=true)
 
void computeLinearSystemTags (const NumericVector< libMesh::Number > &soln, const std::set< TagID > &vector_tags, const std::set< TagID > &matrix_tags, const bool compute_gradients=true)
 
virtual Real computeDamping (const NumericVector< libMesh::Number > &soln, const NumericVector< libMesh::Number > &update)
 
virtual bool shouldUpdateSolution ()
 
virtual bool updateSolution (NumericVector< libMesh::Number > &vec_solution, NumericVector< libMesh::Number > &ghosted_solution)
 
virtual void predictorCleanup (NumericVector< libMesh::Number > &ghosted_solution)
 
virtual void computeBounds (libMesh::NonlinearImplicitSystem &sys, NumericVector< libMesh::Number > &lower, NumericVector< libMesh::Number > &upper)
 
virtual void computeNearNullSpace (libMesh::NonlinearImplicitSystem &sys, std::vector< NumericVector< libMesh::Number > * > &sp)
 
virtual void computeNullSpace (libMesh::NonlinearImplicitSystem &sys, std::vector< NumericVector< libMesh::Number > * > &sp)
 
virtual void computeTransposeNullSpace (libMesh::NonlinearImplicitSystem &sys, std::vector< NumericVector< libMesh::Number > * > &sp)
 
virtual void computePostCheck (libMesh::NonlinearImplicitSystem &sys, const NumericVector< libMesh::Number > &old_soln, NumericVector< libMesh::Number > &search_direction, NumericVector< libMesh::Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln)
 
virtual void computeIndicatorsAndMarkers ()
 
virtual void computeIndicators ()
 
virtual void computeMarkers ()
 
virtual void addResidual (const THREAD_ID tid) override
 
virtual void addResidualNeighbor (const THREAD_ID tid) override
 
virtual void addResidualLower (const THREAD_ID tid) override
 
virtual void addResidualScalar (const THREAD_ID tid=0)
 
virtual void cacheResidual (const THREAD_ID tid) override
 
virtual void cacheResidualNeighbor (const THREAD_ID tid) override
 
virtual void addCachedResidual (const THREAD_ID tid) override
 
virtual void addCachedResidualDirectly (NumericVector< libMesh::Number > &residual, const THREAD_ID tid)
 
virtual void setResidual (NumericVector< libMesh::Number > &residual, const THREAD_ID tid) override
 
virtual void setResidual (libMesh::NumericVector< libMesh::Number > &residual, const THREAD_ID tid)=0
 
virtual void setResidualNeighbor (NumericVector< libMesh::Number > &residual, const THREAD_ID tid) override
 
virtual void setResidualNeighbor (libMesh::NumericVector< libMesh::Number > &residual, const THREAD_ID tid)=0
 
virtual void addJacobian (const THREAD_ID tid) override
 
virtual void addJacobianNeighbor (const THREAD_ID tid) override
 
virtual void addJacobianNeighbor (libMesh::SparseMatrix< libMesh::Number > &jacobian, unsigned int ivar, unsigned int jvar, const DofMap &dof_map, std::vector< dof_id_type > &dof_indices, std::vector< dof_id_type > &neighbor_dof_indices, const std::set< TagID > &tags, const THREAD_ID tid) override
 
virtual void addJacobianNeighbor (libMesh::SparseMatrix< libMesh::Number > &jacobian, unsigned int ivar, unsigned int jvar, const libMesh::DofMap &dof_map, std::vector< dof_id_type > &dof_indices, std::vector< dof_id_type > &neighbor_dof_indices, const std::set< TagID > &tags, const THREAD_ID tid)=0
 
virtual void addJacobianNeighborLowerD (const THREAD_ID tid) override
 
virtual void addJacobianLowerD (const THREAD_ID tid) override
 
virtual void addJacobianBlockTags (libMesh::SparseMatrix< libMesh::Number > &jacobian, unsigned int ivar, unsigned int jvar, const DofMap &dof_map, std::vector< dof_id_type > &dof_indices, const std::set< TagID > &tags, const THREAD_ID tid)
 
virtual void addJacobianScalar (const THREAD_ID tid=0)
 
virtual void addJacobianOffDiagScalar (unsigned int ivar, const THREAD_ID tid=0)
 
virtual void cacheJacobian (const THREAD_ID tid) override
 
virtual void cacheJacobianNeighbor (const THREAD_ID tid) override
 
virtual void addCachedJacobian (const THREAD_ID tid) override
 
virtual void prepareShapes (unsigned int var, const THREAD_ID tid) override
 
virtual void prepareFaceShapes (unsigned int var, const THREAD_ID tid) override
 
virtual void prepareNeighborShapes (unsigned int var, const THREAD_ID tid) override
 
virtual void addDisplacedProblem (std::shared_ptr< DisplacedProblem > displaced_problem)
 
virtual std::shared_ptr< const DisplacedProblemgetDisplacedProblem () const
 
virtual std::shared_ptr< DisplacedProblemgetDisplacedProblem ()
 
virtual void updateGeomSearch (GeometricSearchData::GeometricSearchType type=GeometricSearchData::ALL) override
 
virtual void updateMortarMesh ()
 
void createMortarInterface (const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced, bool periodic, const bool debug, const bool correct_edge_dropping, const Real minimum_projection_angle, const Mortar3DSubpatchPlane mortar_3d_subpatch_plane, const MooseEnum &triangulation, const bool triangulate_triangles, const Mortar3DQuadraturePointMapping mortar_3d_qp_mapping=Mortar3DQuadraturePointMapping::NORMAL_PROJECTION)
 
const std::unordered_map< std::pair< BoundaryID, BoundaryID >, MortarInterfaceConfig > & getMortarInterfaces (bool on_displaced) const
 
virtual void possiblyRebuildGeomSearchPatches ()
 
virtual GeometricSearchDatageomSearchData () override
 
void setRestartFile (const std::string &file_name)
 
const MaterialPropertyRegistrygetMaterialPropertyRegistry () const
 
const InitialConditionWarehousegetInitialConditionWarehouse () const
 
const FVInitialConditionWarehousegetFVInitialConditionWarehouse () const
 
SolverParamssolverParams (unsigned int solver_sys_num=0)
 
const SolverParamssolverParams (unsigned int solver_sys_num=0) const
 
Adaptivityadaptivity ()
 
virtual void initialAdaptMesh ()
 
virtual bool adaptMesh ()
 
unsigned int getNumCyclesCompleted ()
 
bool hasInitialAdaptivity () const
 
bool hasInitialAdaptivity () const
 
void initXFEM (std::shared_ptr< XFEMInterface > xfem)
 
std::shared_ptr< XFEMInterfacegetXFEM ()
 
bool haveXFEM ()
 
virtual bool updateMeshXFEM ()
 
virtual void meshChanged (bool intermediate_change, bool contract_mesh, bool clean_refinement_flags)
 
void notifyWhenMeshChanges (MeshChangedInterface *mci)
 
void notifyWhenMeshDisplaces (MeshDisplacedInterface *mdi)
 
void initElementStatefulProps (const libMesh::ConstElemRange &elem_range, const bool threaded)
 
void initKokkosStatefulProps ()
 
virtual void checkProblemIntegrity ()
 
void registerRandomInterface (RandomInterface &random_interface, const std::string &name)
 
void setConstJacobian (bool state)
 
void setKernelCoverageCheck (CoverageCheckMode mode)
 
void setKernelCoverageCheck (bool flag)
 
void setKernelCoverageCheck (CoverageCheckMode mode)
 
void setMaterialCoverageCheck (CoverageCheckMode mode)
 
void setMaterialCoverageCheck (bool flag)
 
void setMaterialCoverageCheck (CoverageCheckMode mode)
 
void setParallelBarrierMessaging (bool flag)
 
void setVerboseProblem (bool verbose)
 
bool verboseMultiApps () const
 
void parentOutputPositionChanged ()
 
unsigned int subspaceDim (const std::string &prefix) const
 
const MooseObjectWarehouse< Function > & getFunctionWarehouse ()
 
const MaterialWarehousegetMaterialWarehouse () const
 
const MaterialWarehousegetRegularMaterialsWarehouse () const
 
const MaterialWarehousegetDiscreteMaterialWarehouse () const
 
const MaterialWarehousegetInterfaceMaterialsWarehouse () const
 
const MaterialWarehousegetKokkosMaterialsWarehouse () const
 
std::shared_ptr< MaterialBasegetMaterial (std::string name, Moose::MaterialDataType type, const THREAD_ID tid=0, bool no_warn=false)
 
MaterialDatagetMaterialData (Moose::MaterialDataType type, const THREAD_ID tid=0, const MooseObject *object=nullptr) const
 
MaterialDatagetKokkosMaterialData (Moose::MaterialDataType type, const MooseObject *object=nullptr) const
 
const std::set< const MooseObject *> & getMaterialPropertyStorageConsumers (Moose::MaterialDataType type) const
 
const std::set< const MooseObject *> & getKokkosMaterialPropertyStorageConsumers (Moose::MaterialDataType type) const
 
bool restoreOriginalNonzeroPattern () const
 
bool errorOnJacobianNonzeroReallocation () const
 
void setErrorOnJacobianNonzeroReallocation (bool state)
 
bool preserveMatrixSparsityPattern () const
 
void setPreserveMatrixSparsityPattern (bool preserve)
 
bool ignoreZerosInJacobian () const
 
void setIgnoreZerosInJacobian (bool state)
 
bool acceptInvalidSolution () const
 
bool allowInvalidSolution () const
 
bool showInvalidSolutionConsole () const
 
bool immediatelyPrintInvalidSolution () const
 
bool hasTimeIntegrator () const
 
virtual void execute (const ExecFlagType &exec_type)
 
virtual void executeAllObjects (const ExecFlagType &exec_type)
 
virtual ExecutorgetExecutor (const std::string &name)
 
virtual void computeUserObjects (const ExecFlagType &type, const Moose::AuxGroup &group)
 
virtual void computeUserObjectByName (const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
 
void needsPreviousNewtonIteration (bool state)
 
bool needsPreviousNewtonIteration () const
 
void needsPreviousMultiAppFixedPointIterationSolution (bool needed, const unsigned int solver_sys_num)
 
bool needsPreviousMultiAppFixedPointIterationSolution (const unsigned int solver_sys_num) const
 
void needsPreviousMultiAppFixedPointIterationAuxiliary (bool state)
 
bool needsPreviousMultiAppFixedPointIterationAuxiliary () const
 
ExecuteMooseObjectWarehouse< Control > & getControlWarehouse ()
 
void executeControls (const ExecFlagType &exec_type)
 
void executeSamplers (const ExecFlagType &exec_type)
 
virtual void updateActiveObjects ()
 
void reportMooseObjectDependency (MooseObject *a, MooseObject *b)
 
ExecuteMooseObjectWarehouse< MultiApp > & getMultiAppWarehouse ()
 
bool hasJacobian () const
 
bool constJacobian () const
 
void addOutput (const std::string &, const std::string &, InputParameters &)
 
TheWarehousetheWarehouse () const
 
void setSNESMFReuseBase (bool reuse, bool set_by_user)
 
bool useSNESMFReuseBase ()
 
void skipExceptionCheck (bool skip_exception_check)
 
bool isSNESMFReuseBaseSetbyUser ()
 
bool & petscOptionsInserted ()
 
PetscOptions & petscOptionsDatabase ()
 
virtual void setUDotRequested (const bool u_dot_requested)
 
virtual void setUDotDotRequested (const bool u_dotdot_requested)
 
virtual void setUDotOldRequested (const bool u_dot_old_requested)
 
virtual void setUDotDotOldRequested (const bool u_dotdot_old_requested)
 
virtual bool uDotRequested ()
 
virtual bool uDotDotRequested ()
 
virtual bool uDotOldRequested ()
 
virtual bool uDotDotOldRequested ()
 
void haveADObjects (bool have_ad_objects) override
 
virtual void haveADObjects (bool have_ad_objects)
 
bool haveADObjects () const
 
bool haveADObjects () const
 
bool shouldSolve () const
 
const MortarInterfaceWarehousemortarData () const
 
MortarInterfaceWarehousemortarData ()
 
virtual bool hasNeighborCoupling () const
 
virtual bool hasMortarCoupling () const
 
void computingNonlinearResid (bool computing_nonlinear_residual) final
 
bool computingNonlinearResid () const
 
virtual void computingNonlinearResid (const bool computing_nonlinear_residual)
 
bool computingNonlinearResid () const
 
void setCurrentlyComputingResidual (bool currently_computing_residual) final
 
void numGridSteps (unsigned int num_grid_steps)
 
void uniformRefine ()
 
void automaticScaling (bool automatic_scaling) override
 
virtual void automaticScaling (bool automatic_scaling)
 
bool automaticScaling () const
 
bool automaticScaling () const
 
virtual void reinitElemFaceRef (const Elem *elem, unsigned int side, Real tolerance, const std::vector< Point > *const pts, const std::vector< Real > *const weights=nullptr, const THREAD_ID tid=0) override
 
virtual void reinitNeighborFaceRef (const Elem *neighbor_elem, unsigned int neighbor_side, Real tolerance, const std::vector< Point > *const pts, const std::vector< Real > *const weights=nullptr, const THREAD_ID tid=0) override
 
bool fvBCsIntegrityCheck () const
 
void fvBCsIntegrityCheck (bool fv_bcs_integrity_check)
 
void getFVMatsAndDependencies (SubdomainID block_id, std::vector< std::shared_ptr< MaterialBase >> &face_materials, std::vector< std::shared_ptr< MaterialBase >> &neighbor_materials, std::set< MooseVariableFieldBase * > &variables, const THREAD_ID tid)
 
void resizeMaterialData (Moose::MaterialDataType data_type, unsigned int nqp, const THREAD_ID tid)
 
bool haveDisplaced () const override final
 
bool hasLinearConvergenceObjects () const
 
void setNonlinearConvergenceNames (const std::vector< ConvergenceName > &convergence_names)
 
void setLinearConvergenceNames (const std::vector< ConvergenceName > &convergence_names)
 
void setMultiAppFixedPointConvergenceName (const ConvergenceName &convergence_name)
 
void setSteadyStateConvergenceName (const ConvergenceName &convergence_name)
 
const std::vector< ConvergenceName > & getNonlinearConvergenceNames () const
 
const std::vector< ConvergenceName > & getLinearConvergenceNames () const
 
const ConvergenceName & getMultiAppFixedPointConvergenceName () const
 
const ConvergenceName & getSteadyStateConvergenceName () const
 
void computingScalingJacobian (bool computing_scaling_jacobian)
 
bool computingScalingJacobian () const override final
 
void computingScalingResidual (bool computing_scaling_residual)
 
bool computingScalingResidual () const override final
 
MooseAppCoordTransformcoordTransform ()
 
virtual std::size_t numNonlinearSystems () const override
 
virtual std::size_t numLinearSystems () const override
 
virtual std::size_t numSolverSystems () const override
 
bool isSolverSystemNonlinear (const unsigned int sys_num)
 
virtual unsigned int currentNlSysNum () const override
 
virtual unsigned int currentLinearSysNum () const override
 
virtual unsigned int nlSysNum (const NonlinearSystemName &nl_sys_name) const override
 
unsigned int linearSysNum (const LinearSystemName &linear_sys_name) const override
 
unsigned int solverSysNum (const SolverSystemName &solver_sys_name) const override
 
unsigned int systemNumForVariable (const VariableName &variable_name) const
 
bool getFailNextNonlinearConvergenceCheck () const
 
bool getFailNextSystemConvergenceCheck () const
 
void setFailNextNonlinearConvergenceCheck ()
 
void setFailNextSystemConvergenceCheck ()
 
void resetFailNextNonlinearConvergenceCheck ()
 
void resetFailNextSystemConvergenceCheck ()
 
void setExecutionPrinting (const ExecFlagEnum &print_exec)
 
bool shouldPrintExecution (const THREAD_ID tid) const
 
void reinitMortarUserObjects (BoundaryID primary_boundary_id, BoundaryID secondary_boundary_id, bool displaced)
 
virtual const std::vector< VectorTag > & currentResidualVectorTags () const override
 
void setCurrentResidualVectorTags (const std::set< TagID > &vector_tags)
 
void clearCurrentResidualVectorTags ()
 
void clearCurrentJacobianMatrixTags ()
 
virtual void needFV () override
 
virtual bool haveFV () const override
 
virtual bool hasNonlocalCoupling () const override
 
bool identifyVariableGroupsInNL () const
 
virtual void setCurrentLowerDElem (const Elem *const lower_d_elem, const THREAD_ID tid) override
 
virtual void setCurrentBoundaryID (BoundaryID bid, const THREAD_ID tid) override
 
const std::vector< NonlinearSystemName > & getNonlinearSystemNames () const
 
const std::vector< LinearSystemName > & getLinearSystemNames () const
 
const std::vector< SolverSystemName > & getSolverSystemNames () const
 
virtual const libMesh::CouplingMatrixnonlocalCouplingMatrix (const unsigned i) const override
 
virtual bool checkNonlocalCouplingRequirement () const override
 
virtual Moose::FEBackend feBackend () const
 
void createTagMatrices (CreateTaggedMatrixKey)
 
bool useHashTableMatrixAssembly () const
 
bool hasKokkosObjects () const
 
bool hasKokkosResidualObjects () const
 
void addKokkosMeshInitializationHook (std::function< void()> function)
 
const bool & currentlyComputingResidual () const
 
const bool & currentlyComputingResidual () const
 
virtual bool nlConverged (const unsigned int nl_sys_num)
 
virtual bool converged (const unsigned int sys_num)
 
bool defaultGhosting ()
 
virtual TagID addVectorTag (const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
 
void addNotZeroedVectorTag (const TagID tag)
 
bool vectorTagNotZeroed (const TagID tag) const
 
virtual const VectorTaggetVectorTag (const TagID tag_id) const
 
std::vector< VectorTaggetVectorTags (const std::set< TagID > &tag_ids) const
 
virtual const std::vector< VectorTag > & getVectorTags (const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const
 
virtual TagID getVectorTagID (const TagName &tag_name) const
 
virtual TagName vectorTagName (const TagID tag) const
 
virtual bool vectorTagExists (const TagID tag_id) const
 
virtual bool vectorTagExists (const TagName &tag_name) const
 
virtual unsigned int numVectorTags (const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const
 
virtual Moose::VectorTagType vectorTagType (const TagID tag_id) const
 
virtual TagID addMatrixTag (TagName tag_name)
 
virtual TagID getMatrixTagID (const TagName &tag_name) const
 
virtual TagName matrixTagName (TagID tag)
 
virtual bool matrixTagExists (const TagName &tag_name) const
 
virtual bool matrixTagExists (TagID tag_id) const
 
virtual unsigned int numMatrixTags () const
 
virtual std::map< TagName, TagID > & getMatrixTags ()
 
virtual bool hasLinearVariable (const std::string &var_name) const
 
virtual bool hasAuxiliaryVariable (const std::string &var_name) const
 
virtual const std::set< MooseVariableFieldBase *> & getActiveElementalMooseVariables (const THREAD_ID tid) const
 
virtual bool hasActiveElementalMooseVariables (const THREAD_ID tid) const
 
Moose::CoordinateSystemType getCoordSystem (SubdomainID sid) const
 
unsigned int getAxisymmetricRadialCoord () const
 
virtual DiracKernelInfodiracKernelInfo ()
 
void reinitNeighborLowerDElem (const Elem *elem, const THREAD_ID tid=0)
 
void reinitMortarElem (const Elem *elem, const THREAD_ID tid=0)
 
void reinitGeomSearch ()
 
virtual void storeSubdomainMatPropName (SubdomainID block_id, const std::string &name)
 
virtual void storeBoundaryMatPropName (BoundaryID boundary_id, const std::string &name)
 
virtual void storeSubdomainZeroMatProp (SubdomainID block_id, const MaterialPropertyName &name)
 
virtual void storeBoundaryZeroMatProp (BoundaryID boundary_id, const MaterialPropertyName &name)
 
virtual void storeSubdomainDelayedCheckMatProp (const std::string &requestor, SubdomainID block_id, const std::string &name)
 
virtual void storeBoundaryDelayedCheckMatProp (const std::string &requestor, BoundaryID boundary_id, const std::string &name)
 
virtual void checkBlockMatProps ()
 
virtual void checkBoundaryMatProps ()
 
virtual void markMatPropRequested (const std::string &)
 
virtual bool isMatPropRequested (const std::string &prop_name) const
 
void addConsumedPropertyName (const MooseObjectName &obj_name, const std::string &prop_name)
 
const std::map< MooseObjectName, std::set< std::string > > & getConsumedPropertyMap () const
 
virtual std::set< SubdomainIDgetMaterialPropertyBlocks (const std::string &prop_name)
 
virtual std::vector< SubdomainName > getMaterialPropertyBlockNames (const std::string &prop_name)
 
virtual bool hasBlockMaterialProperty (SubdomainID block_id, const std::string &prop_name)
 
virtual std::set< BoundaryIDgetMaterialPropertyBoundaryIDs (const std::string &prop_name)
 
virtual std::vector< BoundaryName > getMaterialPropertyBoundaryNames (const std::string &prop_name)
 
virtual bool hasBoundaryMaterialProperty (BoundaryID boundary_id, const std::string &prop_name)
 
virtual std::set< dof_id_type > & ghostedElems ()
 
const bool & currentlyComputingJacobian () const
 
void setCurrentlyComputingJacobian (const bool currently_computing_jacobian)
 
const bool & currentlyComputingResidualAndJacobian () const
 
void setCurrentlyComputingResidualAndJacobian (bool currently_computing_residual_and_jacobian)
 
virtual bool safeAccessTaggedMatrices () const
 
virtual bool safeAccessTaggedVectors () const
 
const std::set< TagID > & getActiveScalarVariableCoupleableVectorTags (const THREAD_ID tid) const
 
const std::set< TagID > & getActiveScalarVariableCoupleableMatrixTags (const THREAD_ID tid) const
 
const std::set< TagID > & getActiveFEVariableCoupleableVectorTags (const THREAD_ID tid) const
 
const std::set< TagID > & getActiveFEVariableCoupleableMatrixTags (const THREAD_ID tid) const
 
void addAlgebraicGhostingFunctor (libMesh::GhostingFunctor &algebraic_gf, bool to_mesh=true)
 
void addCouplingGhostingFunctor (libMesh::GhostingFunctor &coupling_gf, bool to_mesh=true)
 
void removeAlgebraicGhostingFunctor (libMesh::GhostingFunctor &algebraic_gf)
 
void removeCouplingGhostingFunctor (libMesh::GhostingFunctor &coupling_gf)
 
void hasScalingVector (const unsigned int nl_sys_num)
 
void clearAllDofIndices ()
 
const Moose::Functor< T > & getFunctor (const std::string &name, const THREAD_ID tid, const std::string &requestor_name, bool requestor_is_ad)
 
bool hasFunctor (const std::string &name, const THREAD_ID tid) const
 
bool hasFunctorWithType (const std::string &name, const THREAD_ID tid) const
 
void addFunctor (const std::string &name, const Moose::FunctorBase< T > &functor, const THREAD_ID tid)
 
const Moose::FunctorBase< T > & addPiecewiseByBlockLambdaFunctor (const std::string &name, PolymorphicLambda my_lammy, const std::set< ExecFlagType > &clearance_schedule, const MooseMesh &mesh, const std::set< SubdomainID > &block_ids, const THREAD_ID tid)
 
void setFunctorOutput (bool set_output)
 
void setChainControlDataOutput (bool set_output)
 
void registerUnfilledFunctorRequest (T *functor_interface, const std::string &functor_name, const THREAD_ID tid)
 
void reinitFVFace (const THREAD_ID tid, const FaceInfo &fi)
 
void preparePRefinement ()
 
bool doingPRefinement () const
 
bool havePRefinement () const
 
void markFamilyPRefinement (const InputParameters &params)
 
MooseVariableFEBasegetVariableHelper (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type, Moose::VarFieldType expected_var_field_type, const std::vector< T > &systems, const SystemBase &aux) const
 
void _setCLIOption ()
 
virtual void terminateSolve ()
 
virtual bool isSolveTerminationRequested () const
 
const ConsoleStreamconsole () const
 
virtual bool enabled () const
 
std::shared_ptr< MooseObjectgetSharedPtr ()
 
std::shared_ptr< const MooseObjectgetSharedPtr () const
 
bool isKokkosObject () const
 
MooseAppgetMooseApp () const
 
const std::string & type () const
 
const std::string & name () const
 
std::string typeAndName () const
 
MooseObjectParameterName uniqueParameterName (const std::string &parameter_name) const
 
MooseObjectName uniqueName () const
 
const InputParametersparameters () const
 
const hit::Node * getHitNode () const
 
bool hasBase () const
 
const std::string & getBase () const
 
const TgetParam (const std::string &name) const
 
std::vector< std::pair< T1, T2 > > getParam (const std::string &param1, const std::string &param2) const
 
const TqueryParam (const std::string &name) const
 
const TgetRenamedParam (const std::string &old_name, const std::string &new_name) const
 
T getCheckedPointerParam (const std::string &name, const std::string &error_string="") const
 
bool isParamValid (const std::string &name) const
 
bool isParamSetByUser (const std::string &name) const
 
void connectControllableParams (const std::string &parameter, const std::string &object_type, const std::string &object_name, const std::string &object_parameter) const
 
void paramError (const std::string &param, Args... args) const
 
void paramWarning (const std::string &param, Args... args) const
 
void paramWarning (const std::string &param, Args... args) const
 
void paramInfo (const std::string &param, Args... args) const
 
std::string messagePrefix (const bool hit_prefix=true) const
 
std::string errorPrefix (const std::string &) const
 
void mooseError (Args &&... args) const
 
void mooseDocumentedError (const std::string &repo_name, const unsigned int issue_num, Args &&... args) const
 
void mooseErrorNonPrefixed (Args &&... args) const
 
void mooseWarning (Args &&... args) const
 
void mooseWarning (Args &&... args) const
 
void mooseWarningNonPrefixed (Args &&... args) const
 
void mooseWarningNonPrefixed (Args &&... args) const
 
void mooseDeprecated (Args &&... args) const
 
void mooseDeprecated (Args &&... args) const
 
void mooseDeprecatedNoTrace (Args &&... args) const
 
void mooseInfo (Args &&... args) const
 
void callMooseError (std::string msg, const bool with_prefix, const hit::Node *node=nullptr, const bool show_trace=true) const
 
std::string getDataFileName (const std::string &param) const
 
std::string getDataFileNameByName (const std::string &relative_path) const
 
std::string getDataFilePath (const std::string &relative_path) const
 
PerfGraphperfGraph ()
 
const libMesh::ConstElemRangegetEvaluableElementRange ()
 
const libMesh::ConstElemRangegetEvaluableElementRange ()
 
const libMesh::ConstElemRangegetNonlinearEvaluableElementRange ()
 
const libMesh::ConstElemRangegetNonlinearEvaluableElementRange ()
 
const libMesh::ConstElemRangegetCurrentAlgebraicElementRange ()
 
const libMesh::ConstElemRangegetCurrentAlgebraicElementRange ()
 
const libMesh::ConstNodeRangegetCurrentAlgebraicNodeRange ()
 
const libMesh::ConstNodeRangegetCurrentAlgebraicNodeRange ()
 
const ConstBndNodeRangegetCurrentAlgebraicBndNodeRange ()
 
const ConstBndNodeRangegetCurrentAlgebraicBndNodeRange ()
 
void setCurrentAlgebraicElementRange (libMesh::ConstElemRange *range)
 
void setCurrentAlgebraicElementRange (libMesh::ConstElemRange *range)
 
void setCurrentAlgebraicNodeRange (libMesh::ConstNodeRange *range)
 
void setCurrentAlgebraicNodeRange (libMesh::ConstNodeRange *range)
 
void setCurrentAlgebraicBndNodeRange (ConstBndNodeRange *range)
 
void setCurrentAlgebraicBndNodeRange (ConstBndNodeRange *range)
 
void allowOutput (bool state)
 
void allowOutput (bool state)
 
void allowOutput (bool state)
 
void allowOutput (bool state)
 
Moose::Kokkos::Array< Moose::Kokkos::System > & getKokkosSystems ()
 
const Moose::Kokkos::Array< Moose::Kokkos::System > & getKokkosSystems () const
 
Moose::Kokkos::Array< Moose::Kokkos::System > & getKokkosSystems ()
 
const Moose::Kokkos::Array< Moose::Kokkos::System > & getKokkosSystems () const
 
Moose::Kokkos::Array< Moose::Kokkos::FESystem > & getKokkosFESystems ()
 
const Moose::Kokkos::Array< Moose::Kokkos::FESystem > & getKokkosFESystems () const
 
Moose::Kokkos::Array< Moose::Kokkos::FESystem > & getKokkosFESystems ()
 
const Moose::Kokkos::Array< Moose::Kokkos::FESystem > & getKokkosFESystems () const
 
Moose::Kokkos::SystemgetKokkosSystem (const unsigned int sys_num)
 
const Moose::Kokkos::SystemgetKokkosSystem (const unsigned int sys_num) const
 
Moose::Kokkos::SystemgetKokkosSystem (const unsigned int sys_num)
 
const Moose::Kokkos::SystemgetKokkosSystem (const unsigned int sys_num) const
 
Moose::Kokkos::FESystemgetKokkosFESystem (const unsigned int sys_num)
 
const Moose::Kokkos::FESystemgetKokkosFESystem (const unsigned int sys_num) const
 
Moose::Kokkos::FESystemgetKokkosFESystem (const unsigned int sys_num)
 
const Moose::Kokkos::FESystemgetKokkosFESystem (const unsigned int sys_num) const
 
bool hasMultiApps () const
 
bool hasMultiApps (ExecFlagType type) const
 
bool hasMultiApps () const
 
bool hasMultiApps (ExecFlagType type) const
 
bool hasMultiApp (const std::string &name) const
 
bool hasMultiApp (const std::string &name) const
 
const AutomaticMortarGenerationgetMortarInterface (const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced) const
 
AutomaticMortarGenerationgetMortarInterface (const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced)
 
const AutomaticMortarGenerationgetMortarInterface (const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced) const
 
AutomaticMortarGenerationgetMortarInterface (const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced)
 
const MaterialPropertyStoragegetMaterialPropertyStorage ()
 
const MaterialPropertyStoragegetMaterialPropertyStorage ()
 
const MaterialPropertyStoragegetBndMaterialPropertyStorage ()
 
const MaterialPropertyStoragegetBndMaterialPropertyStorage ()
 
const MaterialPropertyStoragegetNeighborMaterialPropertyStorage ()
 
const MaterialPropertyStoragegetNeighborMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosBndMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosBndMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosNeighborMaterialPropertyStorage ()
 
Moose::Kokkos::MaterialPropertyStoragegetKokkosNeighborMaterialPropertyStorage ()
 
const MooseObjectWarehouse< Indicator > & getIndicatorWarehouse ()
 
const MooseObjectWarehouse< Indicator > & getIndicatorWarehouse ()
 
const MooseObjectWarehouse< InternalSideIndicatorBase > & getInternalSideIndicatorWarehouse ()
 
const MooseObjectWarehouse< InternalSideIndicatorBase > & getInternalSideIndicatorWarehouse ()
 
const MooseObjectWarehouse< Marker > & getMarkerWarehouse ()
 
const MooseObjectWarehouse< Marker > & getMarkerWarehouse ()
 
bool needBoundaryMaterialOnSide (BoundaryID bnd_id, const THREAD_ID tid)
 
bool needBoundaryMaterialOnSide (BoundaryID bnd_id, const THREAD_ID tid)
 
bool needInterfaceMaterialOnSide (BoundaryID bnd_id, const THREAD_ID tid)
 
bool needInterfaceMaterialOnSide (BoundaryID bnd_id, const THREAD_ID tid)
 
bool needInternalNeighborSideMaterial (SubdomainID subdomain_id, const THREAD_ID tid)
 
bool needInternalNeighborSideMaterial (SubdomainID subdomain_id, const THREAD_ID tid)
 
const ExecFlagTypegetCurrentExecuteOnFlag () const
 
const ExecFlagTypegetCurrentExecuteOnFlag () const
 
void setCurrentExecuteOnFlag (const ExecFlagType &)
 
void setCurrentExecuteOnFlag (const ExecFlagType &)
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 
bool isDefaultPostprocessorValue (const std::string &param_name, const unsigned int index=0) const
 
bool hasPostprocessorByName (const PostprocessorName &name) const
 
std::size_t coupledPostprocessors (const std::string &param_name) const
 
const PostprocessorName & getPostprocessorName (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValue (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValue (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValueOld (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValueOld (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValueOlder (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValueOlder (const std::string &param_name, const unsigned int index=0) const
 
const PostprocessorValuegetPostprocessorValueOldByName (const PostprocessorName &name) const
 
const PostprocessorValuegetPostprocessorValueOldByName (const PostprocessorName &name) const
 
const PostprocessorValuegetPostprocessorValueOlderByName (const PostprocessorName &name) const
 
const PostprocessorValuegetPostprocessorValueOlderByName (const PostprocessorName &name) const
 

Static Public Member Functions

static InputParameters validParams ()
 
static void callMooseError (MooseApp *const app, const InputParameters &params, std::string msg, const bool with_prefix, const hit::Node *node, const bool show_trace=true)
 
static void selectVectorTagsFromSystem (const SystemBase &system, const std::vector< VectorTag > &input_vector_tags, std::set< TagID > &selected_tags)
 
static void selectMatrixTagsFromSystem (const SystemBase &system, const std::map< TagName, TagID > &input_matrix_tags, std::set< TagID > &selected_tags)
 
static void objectSetupHelper (const std::vector< T * > &objects, const ExecFlagType &exec_flag)
 
static void objectSetupHelper (const std::vector< T * > &objects, const ExecFlagType &exec_flag)
 
static void objectExecuteHelper (const std::vector< T * > &objects)
 
static void objectExecuteHelper (const std::vector< T * > &objects)
 

Public Attributes

struct SubChannel1PhaseProblem::FrictionStruct _friction_args
 
struct SubChannel1PhaseProblem::NusseltStruct _nusselt_args
 
const PostprocessorValue_P_out
 Outlet pressure postprocessor value. More...
 
const SinglePhaseFluidProperties_fp
 Non-owning pointer to fluid properties user object. More...
 
std::map< std::string, std::vector< dof_id_type > > _var_dof_map
 
 usingCombinedWarningSolutionWarnings
 
const ConsoleStream _console
 
std::vector< Real_real_zero
 
std::vector< VariableValue_scalar_zero
 
std::vector< VariableValue_zero
 
std::vector< VariablePhiValue_phi_zero
 
std::vector< MooseArray< ADReal > > _ad_zero
 
std::vector< VariableGradient_grad_zero
 
std::vector< MooseArray< ADRealVectorValue > > _ad_grad_zero
 
std::vector< VariablePhiGradient_grad_phi_zero
 
std::vector< VariableSecond_second_zero
 
std::vector< MooseArray< ADRealTensorValue > > _ad_second_zero
 
std::vector< VariablePhiSecond_second_phi_zero
 
std::vector< Point > _point_zero
 
std::vector< VectorVariableValue_vector_zero
 
std::vector< VectorVariableCurl_vector_curl_zero
 

Static Public Attributes

static const std::string type_param
 
static const std::string name_param
 
static const std::string unique_name_param
 
static const std::string app_param
 
static const std::string moose_base_param
 
static const std::string kokkos_object_param
 

Protected Member Functions

virtual void initializeSolution () override
 Function to initialize the solution & geometry fields. More...
 
virtual Real computeAddedHeatPin (unsigned int i_ch, unsigned int iz) const override
 Pure virtual: daughters provide different implementations. More...
 
virtual Real getSubChannelPeripheralDuctWidth (unsigned int i_ch) const override
 Function that computes the width of the duct cell that the peripheral subchannel i_ch sees. More...
 
virtual void computeh (int iblock) override
 Computes Enthalpy per channel for block iblock. More...
 
PetscErrorCode cleanUp ()
 
virtual Real computeAddedHeatDuct (unsigned int i_ch, unsigned int iz) const
 Non-pure: implemented in the base (or override in a child if needed) More...
 
void computeWijFromSolve (int iblock)
 Computes diversion crossflow per gap for block iblock. More...
 
void computeSumWij (int iblock)
 Computes net diversion crossflow per channel for block iblock. More...
 
void computeMdot (int iblock)
 Computes mass flow per channel for block iblock. More...
 
void computeWijPrime (int iblock)
 Computes turbulent crossflow per gap for block iblock. More...
 
Real computeMixingParameter (unsigned int i_gap, unsigned int iz) const
 Computes and validates the turbulent mixing parameter. More...
 
Real computeSweepFlowMixingParameter (unsigned int i_gap, unsigned int iz) const
 Computes and validates the sweep-flow mixing parameter. More...
 
void computeDP (int iblock)
 Computes Pressure Drop per channel for block iblock. More...
 
void computeP (int iblock)
 Computes Pressure per channel for block iblock. More...
 
void computeT (int iblock)
 Computes Temperature per channel for block iblock. More...
 
void computeRho (int iblock)
 Computes Density per channel for block iblock. More...
 
void computeMu (int iblock)
 Computes Viscosity per channel for block iblock. More...
 
void computeWijResidual (int iblock)
 Computes Residual Matrix based on the lateral momentum conservation equation for block iblock. More...
 
libMesh::DenseVector< RealresidualFunction (int iblock, libMesh::DenseVector< Real > solution)
 Computes Residual Vector based on the lateral momentum conservation equation for block iblock & updates flow variables based on current crossflow solution. More...
 
PetscErrorCode petscSnesSolver (int iblock, const libMesh::DenseVector< Real > &solution, libMesh::DenseVector< Real > &root)
 Computes solution of nonlinear equation using snes and provided a residual in a formFunction. More...
 
PetscErrorCode implicitPetscSolve (int iblock)
 Computes implicit solve using PetSc. More...
 
void detectDeformation ()
 Detects whether pin diameter or duct displacement fields require geometry recalculation. More...
 
PetscScalar computeInterpolationCoefficients (PetscScalar Peclet=0.0)
 Functions that computes the interpolation scheme given the Peclet number. More...
 
PetscScalar computeInterpolatedValue (PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
 
Real computeGravityDir (const MooseEnum &dir) const
 inline function that is used to define the gravity direction More...
 
PetscErrorCode solveAndPopulateEnthalpy (Mat A, Vec rhs, unsigned int first_node, unsigned int last_node, const char *ksp_prefix)
 Solve a linear system (A * x = rhs) with a simple PCJACOBI KSP and populate the enthalpy solution into _h_soln for nodes [first_node, last_node]. More...
 
PetscErrorCode createPetscVector (Vec &v, PetscInt n)
 Petsc Functions. More...
 
PetscErrorCode createPetscMatrix (Mat &M, PetscInt n, PetscInt m)
 
template<class T >
PetscErrorCode populateVectorFromDense (Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
 
template<class T >
PetscErrorCode populateDenseFromVector (const Vec &x, T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
 
template<class T >
PetscErrorCode populateVectorFromHandle (Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
 
template<class T >
PetscErrorCode populateSolutionChan (const Vec &x, T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
 
virtual void meshChanged ()
 
MooseVariableFieldBasegetVariableHelper (const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type, Moose::VarFieldType expected_var_field_type, const std::vector< T > &nls, const SystemBase &aux) const
 
void createTagVectors ()
 
void createTagSolutions ()
 
virtual void meshDisplaced ()
 
void computeSystems (const ExecFlagType &type)
 
bool duplicateVariableCheck (const std::string &var_name, const libMesh::FEType &type, bool is_aux, const std::set< SubdomainID > *const active_subdomains)
 
void computeUserObjectsInternal (const ExecFlagType &type, TheWarehouse::Query &query)
 
void computeKokkosUserObjectsInternal (const ExecFlagType &type, TheWarehouse::Query &query)
 
void checkDisplacementOrders ()
 
void checkUserObjects ()
 
void checkDependMaterialsHelper (const std::map< SubdomainID, std::vector< std::shared_ptr< MaterialBase >>> &materials_map)
 
void checkCoordinateSystems ()
 
void reinitBecauseOfGhostingOrNewGeomObjects (bool mortar_changed=false)
 
void addObjectParamsHelper (InputParameters &params, const std::string &object_name, const std::string &var_param_name="variable")
 
bool verifyVectorTags () const
 
void flagInvalidSolutionInternal (const InvalidSolutionID invalid_solution_id) const
 
InvalidSolutionID registerInvalidSolutionInternal (const std::string &message, const bool warning) const
 
PerfID registerTimedSection (const std::string &section_name, const unsigned int level) const
 
PerfID registerTimedSection (const std::string &section_name, const unsigned int level, const std::string &live_message, const bool print_dots=true) const
 
std::string timedSectionName (const std::string &section_name) const
 
TdeclareRestartableData (const std::string &data_name, Args &&... args)
 
ManagedValue< TdeclareManagedRestartableDataWithContext (const std::string &data_name, void *context, Args &&... args)
 
const TgetRestartableData (const std::string &data_name) const
 
TdeclareRestartableDataWithContext (const std::string &data_name, void *context, Args &&... args)
 
TdeclareRecoverableData (const std::string &data_name, Args &&... args)
 
TdeclareRestartableDataWithObjectName (const std::string &data_name, const std::string &object_name, Args &&... args)
 
TdeclareRestartableDataWithObjectNameWithContext (const std::string &data_name, const std::string &object_name, void *context, Args &&... args)
 
std::string restartableName (const std::string &data_name) const
 
virtual void addPostprocessorDependencyHelper (const PostprocessorName &) const
 

Protected Attributes

TriSubChannelMesh_tri_sch_mesh
 
Mat _hc_axial_heat_conduction_mat
 
Vec _hc_axial_heat_conduction_rhs
 
Mat _hc_radial_heat_conduction_mat
 
Vec _hc_radial_heat_conduction_rhs
 
Mat _hc_sweep_enthalpy_mat
 
Vec _hc_sweep_enthalpy_rhs
 
SubChannelMesh_subchannel_mesh
 
unsigned int _n_blocks
 number of axial blocks More...
 
libMesh::DenseMatrix< Real_DP
 
libMesh::DenseMatrix< Real > & _Wij
 
libMesh::DenseMatrix< Real_Wij_old
 
libMesh::DenseMatrix< Real_WijPrime
 
libMesh::DenseMatrix< Real_Wij_residual_matrix
 
const Real _g_grav
 
const Real_kij
 
unsigned int _n_cells
 
unsigned int _n_gaps
 
unsigned int _n_pins
 
unsigned int _n_channels
 
unsigned int _block_size
 
std::vector< Real_z_grid
 axial location of nodes More...
 
Real _one
 
Real _TR
 Flag that activates or deactivates the transient parts of the equations we solve by multiplication. More...
 
const bool _compute_density
 Flag that activates or deactivates the calculation of density. More...
 
const bool _compute_viscosity
 Flag that activates or deactivates the calculation of viscosity. More...
 
const bool _compute_power
 Flag that informs if we need to solve the Enthalpy/Temperature equations or not. More...
 
const bool _pin_mesh_exist
 Flag that informs if there is a pin mesh or not. More...
 
const bool _duct_mesh_exist
 Flag that informs if there is a duct mesh or not. More...
 
bool _converged
 Variable that informs whether we exited external solve with a converged solution or not. More...
 
bool _time_integrator_checked = false
 Whether the time integrator has been checked for consistency with the implementation. More...
 
Real _dt
 Time step. More...
 
Real _CT
 Turbulent modeling parameter used in axial momentum equation. More...
 
const Real_P_tol
 Convergence tolerance for the pressure loop in external solve. More...
 
const Real_T_tol
 Convergence tolerance for the temperature loop in internal solve. More...
 
const int_T_maxit
 Maximum iterations for the inner temperature loop. More...
 
const PetscReal & _rtol
 The relative convergence tolerance, (relative decrease) for the ksp linear solver. More...
 
const PetscReal & _atol
 The absolute convergence tolerance for the ksp linear solver. More...
 
const PetscReal & _dtol
 The divergence tolerance for the ksp linear solver. More...
 
const PetscInt & _maxit
 The maximum number of iterations to use for the ksp linear solver. More...
 
const MooseEnum _interpolation_scheme
 The interpolation method used in constructing the systems. More...
 
const MooseEnum _gravity_direction
 The direction of gravity. More...
 
const Real _dir_grav
 
const bool _implicit_bool
 Flag to define the usage of a implicit or explicit solution. More...
 
const bool _staggered_pressure_bool
 Flag to define the usage of staggered or collocated pressure. More...
 
const bool _segregated_bool
 Segregated solve. More...
 
const bool _verbose_subchannel
 Boolean to printout information related to subchannel solve. More...
 
bool _deformation = false
 Flag that activates the effect of deformation (pin/duct) based on the auxvalues for displacement, Dpin. More...
 
const SCMFrictionClosureBase_friction_closure
 Friction closure object. More...
 
const SCMMixingClosureBase_mixing_closure
 Turbulent Mixing closure object. More...
 
const SCMHTCClosureBase_pin_HTC_closure
 HTC closure objects. More...
 
const SCMHTCClosureBase_duct_HTC_closure
 
std::unique_ptr< SolutionHandle_mdot_soln
 Solutions handles and link to TH tables properties. More...
 
std::unique_ptr< SolutionHandle_SumWij_soln
 
std::unique_ptr< SolutionHandle_P_soln
 
std::unique_ptr< SolutionHandle_DP_soln
 
std::unique_ptr< SolutionHandle_h_soln
 
std::unique_ptr< SolutionHandle_T_soln
 
std::unique_ptr< SolutionHandle_Tpin_soln
 
std::unique_ptr< SolutionHandle_Dpin_soln
 
std::unique_ptr< SolutionHandle_rho_soln
 
std::unique_ptr< SolutionHandle_mu_soln
 
std::unique_ptr< SolutionHandle_S_flow_soln
 
std::unique_ptr< SolutionHandle_w_perim_soln
 
std::unique_ptr< SolutionHandle_q_prime_soln
 
std::unique_ptr< SolutionHandle_duct_heat_flux_soln
 
std::unique_ptr< SolutionHandle_Tduct_soln
 
std::unique_ptr< SolutionHandle_displacement_soln
 
std::unique_ptr< SolutionHandle_ff_soln
 
std::unique_ptr< SolutionHandle_HTC_soln
 
Mat _mc_sumWij_mat
 Matrices and vectors to be used in implicit assembly Mass conservation Mass conservation - sum of cross fluxes. More...
 
Vec _Wij_vec
 
Vec _prod
 
Vec _prodp
 
Mat _mc_axial_convection_mat
 Mass conservation - axial convection. More...
 
Vec _mc_axial_convection_rhs
 
Mat _amc_turbulent_cross_flows_mat
 Mass conservation - density time derivative No implicit matrix. More...
 
Vec _amc_turbulent_cross_flows_rhs
 
Mat _amc_time_derivative_mat
 Axial momentum conservation - time derivative. More...
 
Vec _amc_time_derivative_rhs
 
Mat _amc_advective_derivative_mat
 Axial momentum conservation - advective (Eulerian) derivative. More...
 
Vec _amc_advective_derivative_rhs
 
Mat _amc_cross_derivative_mat
 Axial momentum conservation - cross flux derivative. More...
 
Vec _amc_cross_derivative_rhs
 
Mat _amc_friction_force_mat
 Axial momentum conservation - friction force. More...
 
Vec _amc_friction_force_rhs
 
Vec _amc_gravity_rhs
 Axial momentum conservation - buoyancy force No implicit matrix. More...
 
Mat _amc_pressure_force_mat
 Axial momentum conservation - pressure force. More...
 
Vec _amc_pressure_force_rhs
 
Mat _amc_sys_mdot_mat
 Axial momentum system matrix. More...
 
Vec _amc_sys_mdot_rhs
 
Mat _cmc_time_derivative_mat
 Cross momentum Cross momentum conservation - time derivative. More...
 
Vec _cmc_time_derivative_rhs
 
Mat _cmc_advective_derivative_mat
 Cross momentum conservation - advective (Eulerian) derivative. More...
 
Vec _cmc_advective_derivative_rhs
 
Mat _cmc_friction_force_mat
 Cross momentum conservation - friction force. More...
 
Vec _cmc_friction_force_rhs
 
Mat _cmc_pressure_force_mat
 Cross momentum conservation - pressure force. More...
 
Vec _cmc_pressure_force_rhs
 
Mat _cmc_sys_Wij_mat
 Lateral momentum system matrix. More...
 
Vec _cmc_sys_Wij_rhs
 
Mat _hc_time_derivative_mat
 Enthalpy Enthalpy conservation - time derivative. More...
 
Vec _hc_time_derivative_rhs
 
Mat _hc_advective_derivative_mat
 Enthalpy conservation - advective (Eulerian) derivative;. More...
 
Vec _hc_advective_derivative_rhs
 
Mat _hc_cross_derivative_mat
 Enthalpy conservation - cross flux derivative. More...
 
Vec _hc_cross_derivative_rhs
 
Vec _hc_added_heat_rhs
 Enthalpy conservation - source and sink. More...
 
Mat _hc_sys_h_mat
 System matrices. More...
 
Vec _hc_sys_h_rhs
 
PetscScalar _added_K = 0.0
 Added resistances for monolithic convergence. More...
 
PetscScalar _added_K_old = 1000.0
 
PetscScalar _max_sumWij
 
PetscScalar _max_sumWij_new
 
PetscScalar _correction_factor = 1.0
 
MooseMesh_mesh
 
bool _initialized
 
std::optional< std::vector< ConvergenceName > > _nonlinear_convergence_names
 
std::optional< std::vector< ConvergenceName > > _linear_convergence_names
 
std::optional< ConvergenceName > _multiapp_fixed_point_convergence_name
 
std::optional< ConvergenceName > _steady_state_convergence_name
 
std::set< TagID_fe_vector_tags
 
std::set< TagID_fe_matrix_tags
 
std::set< TagID_linear_vector_tags
 
std::set< TagID_linear_matrix_tags
 
const bool & _solve
 
bool _transient
 
Real_time
 
Real_time_old
 
int_t_step
 
Real_dt_old
 
bool _need_to_add_default_nonlinear_convergence
 
bool _need_to_add_default_multiapp_fixed_point_convergence
 
bool _need_to_add_default_steady_state_convergence
 
const std::vector< LinearSystemName > _linear_sys_names
 
const std::size_t _num_linear_sys
 
std::vector< std::shared_ptr< LinearSystem > > _linear_systems
 
std::map< LinearSystemName, unsigned int_linear_sys_name_to_num
 
LinearSystem_current_linear_sys
 
const bool _using_default_nl
 
const std::vector< NonlinearSystemName > _nl_sys_names
 
const std::size_t _num_nl_sys
 
std::vector< std::shared_ptr< NonlinearSystemBase > > _nl
 
std::map< NonlinearSystemName, unsigned int_nl_sys_name_to_num
 
NonlinearSystemBase_current_nl_sys
 
SolverSystem_current_solver_sys
 
std::vector< std::shared_ptr< SolverSystem > > _solver_systems
 
std::map< SolverVariableName, unsigned int_solver_var_to_sys_num
 
std::map< SolverSystemName, unsigned int_solver_sys_name_to_num
 
std::vector< SolverSystemName > _solver_sys_names
 
std::shared_ptr< AuxiliarySystem_aux
 
Moose::CouplingType _coupling
 
std::vector< std::unique_ptr< libMesh::CouplingMatrix > > _cm
 
Moose::Kokkos::Array< Moose::Kokkos::System_kokkos_systems
 
Moose::Kokkos::Array< Moose::Kokkos::FESystem_kokkos_fe_systems
 
std::map< std::string, unsigned int_subspace_dim
 
std::vector< std::vector< std::unique_ptr< Assembly > > > _assembly
 
Moose::Kokkos::Assembly _kokkos_assembly
 
MooseObjectWarehouse< MeshDivision_mesh_divisions
 
MooseObjectWarehouse< Function_functions
 
MooseObjectWarehouse< Moose::FunctionBase_kokkos_functions
 
MooseObjectWarehouse< Convergence_convergences
 
MooseObjectWarehouse< KernelBase_nonlocal_kernels
 
MooseObjectWarehouse< IntegratedBCBase_nonlocal_integrated_bcs
 
MaterialPropertyRegistry _material_prop_registry
 
MaterialPropertyStorage_material_props
 
MaterialPropertyStorage_bnd_material_props
 
MaterialPropertyStorage_neighbor_material_props
 
Moose::Kokkos::MaterialPropertyStorage_kokkos_material_props
 
Moose::Kokkos::MaterialPropertyStorage_kokkos_bnd_material_props
 
Moose::Kokkos::MaterialPropertyStorage_kokkos_neighbor_material_props
 
MooseObjectWarehouse< Marker_markers
 
ReporterData _reporter_data
 
ExecuteMooseObjectWarehouse< MultiApp_multi_apps
 
ExecuteMooseObjectWarehouse< TransientMultiApp_transient_multi_apps
 
ExecuteMooseObjectWarehouse< Transfer_transfers
 
ExecuteMooseObjectWarehouse< Transfer_to_multi_app_transfers
 
ExecuteMooseObjectWarehouse< Transfer_from_multi_app_transfers
 
ExecuteMooseObjectWarehouse< Transfer_between_multi_app_transfers
 
std::map< std::string, std::unique_ptr< RandomData > > _random_data_objects
 
std::vector< std::unordered_map< SubdomainID, bool > > _block_mat_side_cache
 
std::vector< std::unordered_map< BoundaryID, bool > > _bnd_mat_side_cache
 
std::vector< std::unordered_map< BoundaryID, bool > > _interface_mat_side_cache
 
std::vector< MeshChangedInterface *> _notify_when_mesh_changes
 
std::vector< MeshDisplacedInterface *> _notify_when_mesh_displaces
 
Adaptivity _adaptivity
 
unsigned int _cycles_completed
 
std::shared_ptr< XFEMInterface_xfem
 
MooseMesh_displaced_mesh
 
std::shared_ptr< DisplacedProblem_displaced_problem
 
GeometricSearchData _geometric_search_data
 
std::unique_ptr< MortarInterfaceWarehouse_mortar_data
 
bool _reinit_displaced_elem
 
bool _reinit_displaced_face
 
bool _reinit_displaced_neighbor
 
bool _input_file_saved
 
bool _has_dampers
 
bool _has_constraints
 
bool _snesmf_reuse_base
 
bool _skip_exception_check
 
bool _snesmf_reuse_base_set_by_user
 
bool _has_initialized_stateful
 
bool _const_jacobian
 
bool _has_jacobian
 
bool _needs_old_newton_iter
 
bool _previous_nl_solution_required
 
std::vector< bool > _previous_multiapp_fp_nl_solution_required
 
bool _previous_multiapp_fp_aux_solution_required
 
bool _has_nonlocal_coupling
 
bool _calculate_jacobian_in_uo
 
std::vector< std::vector< const MooseVariableFEBase *> > _uo_jacobian_moose_vars
 
std::vector< unsigned char > _has_active_material_properties
 
std::vector< SolverParams_solver_params
 
CoverageCheckMode _kernel_coverage_check
 
std::vector< SubdomainName > _kernel_coverage_blocks
 
const bool _boundary_restricted_node_integrity_check
 
const bool _boundary_restricted_elem_integrity_check
 
CoverageCheckMode _material_coverage_check
 
std::vector< SubdomainName > _material_coverage_blocks
 
bool _fv_bcs_integrity_check
 
const bool _material_dependency_check
 
const bool _uo_aux_state_check
 
bool _check_residual_for_nans
 
unsigned int _max_qps
 
libMesh::Order _max_scalar_order
 
bool _has_time_integrator
 
bool _has_exception
 
bool _parallel_barrier_messaging
 
MooseEnum _verbose_setup
 
bool _verbose_multiapps
 
bool _verbose_restore
 
std::string _exception_message
 
ExecFlagType _current_execute_on_flag
 
ExecuteMooseObjectWarehouse< Control_control_warehouse
 
Moose::PetscSupport::PetscOptions _petsc_options
 
PetscOptions _petsc_option_data_base
 
bool _is_petsc_options_inserted
 
std::shared_ptr< LineSearch_line_search
 
std::unique_ptr< libMesh::ConstElemRange_evaluable_local_elem_range
 
std::unique_ptr< libMesh::ConstElemRange_nl_evaluable_local_elem_range
 
std::unique_ptr< libMesh::ConstElemRange_aux_evaluable_local_elem_range
 
std::unique_ptr< libMesh::ConstElemRange_current_algebraic_elem_range
 
std::unique_ptr< libMesh::ConstNodeRange_current_algebraic_node_range
 
std::unique_ptr< ConstBndNodeRange_current_algebraic_bnd_node_range
 
bool _using_ad_mat_props
 
unsigned short _current_ic_state
 
const bool _use_hash_table_matrix_assembly
 
std::map< TagName, TagID_matrix_tag_name_to_tag_id
 
std::map< TagID, TagName > _matrix_tag_id_to_tag_name
 
Factory_factory
 
DiracKernelInfo _dirac_kernel_info
 
std::map< SubdomainID, std::set< std::string > > _map_block_material_props
 
std::map< BoundaryID, std::set< std::string > > _map_boundary_material_props
 
std::map< SubdomainID, std::set< MaterialPropertyName > > _zero_block_material_props
 
std::map< BoundaryID, std::set< MaterialPropertyName > > _zero_boundary_material_props
 
std::set< std::string > _material_property_requested
 
std::vector< std::set< MooseVariableFieldBase *> > _active_elemental_moose_variables
 
std::vector< unsigned int_has_active_elemental_moose_variables
 
std::vector< std::set< TagID > > _active_fe_var_coupleable_matrix_tags
 
std::vector< std::set< TagID > > _active_fe_var_coupleable_vector_tags
 
std::vector< std::set< TagID > > _active_sc_var_coupleable_matrix_tags
 
std::vector< std::set< TagID > > _active_sc_var_coupleable_vector_tags
 
bool _default_ghosting
 
std::set< dof_id_type_ghosted_elems
 
bool _currently_computing_jacobian
 
bool _currently_computing_residual_and_jacobian
 
bool _computing_nonlinear_residual
 
bool _currently_computing_residual
 
bool _safe_access_tagged_matrices
 
bool _safe_access_tagged_vectors
 
bool _have_ad_objects
 
std::unordered_set< TagID_not_zeroed_tagged_vectors
 
bool _cli_option_found
 
bool _color_output
 
bool _termination_requested
 
const bool & _enabled
 
MooseApp_app
 
ActionFactory_action_factory
 
const std::string & _type
 
const std::string & _name
 
const InputParameters_pars
 
MooseApp_pg_moose_app
 
const std::string _prefix
 
MooseApp_restartable_app
 
const std::string _restartable_system_name
 
const THREAD_ID _restartable_tid
 
const bool _restartable_read_only
 
InitialConditionWarehouse _ics
 
FVInitialConditionWarehouse _fv_ics
 
ScalarInitialConditionWarehouse _scalar_ics
 
MaterialWarehouse _materials
 
MaterialWarehouse _interface_materials
 
MaterialWarehouse _discrete_materials
 
MaterialWarehouse _all_materials
 
MaterialWarehouse _kokkos_materials
 
MooseObjectWarehouse< Indicator_indicators
 
MooseObjectWarehouse< InternalSideIndicatorBase_internal_side_indicators
 
std::map< SubdomainID, std::multimap< std::string, std::string > > _map_block_material_props_check
 
std::map< BoundaryID, std::multimap< std::string, std::string > > _map_boundary_material_props_check
 
const Parallel::Communicator & _communicator
 

Detailed Description

Triangular subchannel solver.

Definition at line 19 of file TriSubChannel1PhaseProblem.h.

Constructor & Destructor Documentation

◆ TriSubChannel1PhaseProblem()

TriSubChannel1PhaseProblem::TriSubChannel1PhaseProblem ( const InputParameters params)

Definition at line 31 of file TriSubChannel1PhaseProblem.C.

32  : SubChannel1PhaseProblem(params),
33  _tri_sch_mesh(SCM::getMesh<TriSubChannelMesh>(_subchannel_mesh))
34 {
35  // Initializing heat conduction system
36  LibmeshPetscCall(createPetscMatrix(
39  LibmeshPetscCall(createPetscMatrix(
42  LibmeshPetscCall(createPetscMatrix(
45 }
PetscErrorCode createPetscVector(Vec &v, PetscInt n)
Petsc Functions.
PetscErrorCode createPetscMatrix(Mat &M, PetscInt n, PetscInt m)
SubChannel1PhaseProblem(const InputParameters &params)

◆ ~TriSubChannel1PhaseProblem()

TriSubChannel1PhaseProblem::~TriSubChannel1PhaseProblem ( )
virtual

Definition at line 47 of file TriSubChannel1PhaseProblem.C.

48 {
49  PetscErrorCode ierr = cleanUp();
50  if (ierr)
51  mooseError(name(), ": Error in memory cleanup");
52 }
const std::string & name() const
void mooseError(Args &&... args) const

Member Function Documentation

◆ cleanUp()

PetscErrorCode TriSubChannel1PhaseProblem::cleanUp ( )
protected

Definition at line 55 of file TriSubChannel1PhaseProblem.C.

Referenced by ~TriSubChannel1PhaseProblem().

56 {
58  // Clean up heat conduction system
59  LibmeshPetscCall(MatDestroy(&_hc_axial_heat_conduction_mat));
60  LibmeshPetscCall(VecDestroy(&_hc_axial_heat_conduction_rhs));
61  LibmeshPetscCall(MatDestroy(&_hc_radial_heat_conduction_mat));
62  LibmeshPetscCall(VecDestroy(&_hc_radial_heat_conduction_rhs));
63  LibmeshPetscCall(MatDestroy(&_hc_sweep_enthalpy_mat));
64  LibmeshPetscCall(VecDestroy(&_hc_sweep_enthalpy_rhs));
65  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
66 }
PetscFunctionBegin
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ computeAddedHeatDuct()

Real SubChannel1PhaseProblem::computeAddedHeatDuct ( unsigned int  i_ch,
unsigned int  iz 
) const
protectedvirtualinherited

Non-pure: implemented in the base (or override in a child if needed)

Definition at line 2070 of file SubChannel1PhaseProblem.C.

Referenced by computeh(), and SubChannel1PhaseProblem::getAddedHeatDuct().

2071 {
2072  mooseAssert(iz > 0, "Trapezoidal rule requires starting at index 1 at least");
2073  if (_duct_mesh_exist)
2074  {
2075  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
2076  if (subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER)
2077  {
2078  auto dz = _z_grid[iz] - _z_grid[iz - 1];
2079  auto * node_in_chan = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
2080  auto * node_out_chan = _subchannel_mesh.getChannelNode(i_ch, iz);
2081  auto * node_in_duct = _subchannel_mesh.getDuctNodeFromChannel(node_in_chan);
2082  auto * node_out_duct = _subchannel_mesh.getDuctNodeFromChannel(node_out_chan);
2083  auto heat_rate_in = (*_duct_heat_flux_soln)(node_in_duct);
2084  auto heat_rate_out = (*_duct_heat_flux_soln)(node_out_duct);
2085  auto width = getSubChannelPeripheralDuctWidth(i_ch);
2086  return 0.5 * (heat_rate_in + heat_rate_out) * dz * width;
2087  }
2088  else
2089  {
2090  return 0.0;
2091  }
2092  }
2093  else
2094  {
2095  return 0.0;
2096  }
2097 }
Node * getDuctNodeFromChannel(Node *channel_node) const
Function that gets the duct node from the channel node.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
const bool _duct_mesh_exist
Flag that informs if there is a duct mesh or not.
std::vector< Real > _z_grid
axial location of nodes
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
virtual Real getSubChannelPeripheralDuctWidth(unsigned int i_ch) const =0
Function that computes the width of the duct cell that the peripheral subchannel i_ch sees...

◆ computeAddedHeatPin()

Real TriSubChannel1PhaseProblem::computeAddedHeatPin ( unsigned int  i_ch,
unsigned int  iz 
) const
overrideprotectedvirtual

Pure virtual: daughters provide different implementations.

Implements SubChannel1PhaseProblem.

Definition at line 262 of file TriSubChannel1PhaseProblem.C.

Referenced by computeh().

263 {
264  if (!_pin_mesh_exist)
265  return 0.0;
266 
267  // Compute axial location of nodes.
268  auto z2 = _z_grid[iz];
269  auto z1 = _z_grid[iz - 1];
270  auto heated_length = _subchannel_mesh.getHeatedLength();
271  auto unheated_length_entry = _subchannel_mesh.getHeatedLengthEntry();
272  if (MooseUtils::absoluteFuzzyGreaterThan(z2, unheated_length_entry) &&
273  MooseUtils::absoluteFuzzyLessThan(z1, unheated_length_entry + heated_length))
274  {
275  // Compute the height of this element.
276  auto dz = z2 - z1;
277  Real factor;
278  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
279  switch (subch_type)
280  {
282  factor = 1.0 / 6.0;
283  break;
284  case EChannelType::EDGE:
285  factor = 1.0 / 4.0;
286  break;
288  factor = 1.0 / 6.0;
289  break;
290  default:
291  return 0.0; // handle invalid subch_type if needed
292  }
293  double heat_rate_in = 0.0;
294  double heat_rate_out = 0.0;
295  for (auto i_pin : _subchannel_mesh.getChannelPins(i_ch))
296  {
297  auto * node_in = _subchannel_mesh.getPinNode(i_pin, iz - 1);
298  auto * node_out = _subchannel_mesh.getPinNode(i_pin, iz);
299  heat_rate_out += factor * (*_q_prime_soln)(node_out);
300  heat_rate_in += factor * (*_q_prime_soln)(node_in);
301  }
302  return (heat_rate_in + heat_rate_out) * dz / 2.0;
303  }
304  else
305  return 0.0;
306 }
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
virtual const std::vector< unsigned int > & getChannelPins(unsigned int i_chan) const =0
Return a vector of pin indices for a given channel index.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
virtual Node * getPinNode(unsigned int i_pin, unsigned int iz) const =0
Get the pin mesh node for a given pin index and elevation index.
std::vector< Real > _z_grid
axial location of nodes
virtual const Real & getHeatedLength() const
Return heated length.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Real & getHeatedLengthEntry() const
Return unheated length at entry.

◆ computeDP()

void SubChannel1PhaseProblem::computeDP ( int  iblock)
protectedinherited

Computes Pressure Drop per channel for block iblock.

Upwind local form loss

Upwind local form loss

Time derivative term

Advective derivative term

Cross derivative term

Friction term

Upwind local form loss

Gravity force

Assembling system

Definition at line 680 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

681 {
682  const unsigned int last_node = (iblock + 1) * _block_size;
683  const unsigned int first_node = iblock * _block_size + 1;
684  if (!_implicit_bool)
685  {
686  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
687  {
688  auto k_grid = _subchannel_mesh.getKGrid();
689  auto dz = _z_grid[iz] - _z_grid[iz - 1];
690  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
691  {
692  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
693  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
694  auto rho_in = (*_rho_soln)(node_in);
695  auto rho_out = (*_rho_soln)(node_out);
696  auto mu_in = (*_mu_soln)(node_in);
697  auto S = (*_S_flow_soln)(node_in);
698  auto w_perim = (*_w_perim_soln)(node_in);
699  // hydraulic diameter in the i direction
700  auto Dh_i = 4.0 * S / w_perim;
701  auto time_term = _TR * ((*_mdot_soln)(node_out)-_mdot_soln->old(node_out)) * dz / _dt -
702  dz * 2.0 * (*_mdot_soln)(node_out) * (rho_out - _rho_soln->old(node_out)) /
703  rho_in / _dt;
704  auto mass_term1 =
705  Utility::pow<2>((*_mdot_soln)(node_out)) * (1.0 / S / rho_out - 1.0 / S / rho_in);
706  auto mass_term2 = -2.0 * (*_mdot_soln)(node_out) * (*_SumWij_soln)(node_out) / S / rho_in;
707  auto crossflow_term = 0.0;
708  auto turbulent_term = 0.0;
709  unsigned int counter = 0;
710  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
711  {
712  auto chans = _subchannel_mesh.getGapChannels(i_gap);
713  unsigned int ii_ch = chans.first;
714  unsigned int jj_ch = chans.second;
715  auto * node_in_i = _subchannel_mesh.getChannelNode(ii_ch, iz - 1);
716  auto * node_in_j = _subchannel_mesh.getChannelNode(jj_ch, iz - 1);
717  auto * node_out_i = _subchannel_mesh.getChannelNode(ii_ch, iz);
718  auto * node_out_j = _subchannel_mesh.getChannelNode(jj_ch, iz);
719  auto rho_i = (*_rho_soln)(node_in_i);
720  auto rho_j = (*_rho_soln)(node_in_j);
721  auto Si = (*_S_flow_soln)(node_in_i);
722  auto Sj = (*_S_flow_soln)(node_in_j);
723  Real u_star = 0.0;
724  // figure out donor axial velocity
725  if (_Wij(i_gap, iz) > 0.0)
726  u_star = (*_mdot_soln)(node_out_i) / Si / rho_i;
727  else
728  u_star = (*_mdot_soln)(node_out_j) / Sj / rho_j;
729 
730  crossflow_term +=
731  _subchannel_mesh.getCrossflowSign(i_ch, counter) * _Wij(i_gap, iz) * u_star;
732 
733  turbulent_term += _WijPrime(i_gap, iz) * (2 * (*_mdot_soln)(node_out) / rho_in / S -
734  (*_mdot_soln)(node_out_j) / Sj / rho_j -
735  (*_mdot_soln)(node_out_i) / Si / rho_i);
736  counter++;
737  }
738  turbulent_term *= _CT;
739  auto Re = (((*_mdot_soln)(node_in) / S) * Dh_i / mu_in);
740  _friction_args = FrictionStruct(i_ch, Re, S, w_perim);
742  if (_ff_soln)
743  _ff_soln->set(node_out, ff);
745  auto ki = 0.0;
746  if ((*_mdot_soln)(node_out) >= 0)
747  ki = k_grid[i_ch][iz - 1];
748  else
749  ki = k_grid[i_ch][iz];
750  auto friction_term = (ff * dz / Dh_i + ki) * 0.5 *
751  (*_mdot_soln)(node_out)*std::abs((*_mdot_soln)(node_out)) /
752  (S * (*_rho_soln)(node_out));
753  auto gravity_term = _dir_grav * _g_grav * (*_rho_soln)(node_out)*dz * S;
754  auto DP = (1 / S) * (time_term + mass_term1 + mass_term2 + crossflow_term + turbulent_term +
755  friction_term + gravity_term); // Pa
756  _DP(i_ch, iz) = DP;
757  if (_DP_soln)
758  _DP_soln->set(node_out, DP);
759  }
760  }
761  }
762  else
763  {
764  LibmeshPetscCall(MatZeroEntries(_amc_time_derivative_mat));
765  LibmeshPetscCall(MatZeroEntries(_amc_advective_derivative_mat));
766  LibmeshPetscCall(MatZeroEntries(_amc_cross_derivative_mat));
767  LibmeshPetscCall(MatZeroEntries(_amc_friction_force_mat));
768  LibmeshPetscCall(VecZeroEntries(_amc_time_derivative_rhs));
769  LibmeshPetscCall(VecZeroEntries(_amc_advective_derivative_rhs));
770  LibmeshPetscCall(VecZeroEntries(_amc_cross_derivative_rhs));
771  LibmeshPetscCall(VecZeroEntries(_amc_friction_force_rhs));
772  LibmeshPetscCall(VecZeroEntries(_amc_gravity_rhs));
773  LibmeshPetscCall(MatZeroEntries(_amc_sys_mdot_mat));
774  LibmeshPetscCall(VecZeroEntries(_amc_sys_mdot_rhs));
775  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
776  {
777  auto k_grid = _subchannel_mesh.getKGrid();
778  auto dz = _z_grid[iz] - _z_grid[iz - 1];
779  auto iz_ind = iz - first_node;
780  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
781  {
782  // inlet and outlet nodes
783  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
784  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
785 
786  // interpolation weight coefficient
787  PetscScalar Pe = 0.5;
788  if (_interpolation_scheme == 3)
789  {
790  // Compute the Peclet number
791  auto S_in = (*_S_flow_soln)(node_in);
792  auto S_out = (*_S_flow_soln)(node_out);
793  auto S_interp = computeInterpolatedValue(S_out, S_in, 0.5);
794  auto w_perim_in = (*_w_perim_soln)(node_in);
795  auto w_perim_out = (*_w_perim_soln)(node_out);
796  auto w_perim_interp = this->computeInterpolatedValue(w_perim_out, w_perim_in, 0.5);
797  auto mdot_loc =
798  this->computeInterpolatedValue((*_mdot_soln)(node_out), (*_mdot_soln)(node_in), 0.5);
799  auto mu_in = (*_mu_soln)(node_in);
800  auto mu_out = (*_mu_soln)(node_out);
801  auto mu_interp = this->computeInterpolatedValue(mu_out, mu_in, 0.5);
802  auto Dh_i = 4.0 * S_interp / w_perim_interp;
803  // Compute friction factor
804  auto Re = ((mdot_loc / S_interp) * Dh_i / mu_interp);
805  _friction_args = FrictionStruct(i_ch, Re, S_interp, w_perim_interp);
807  if (_ff_soln)
808  _ff_soln->set(node_out, ff);
810  auto ki = 0.0;
811  if ((*_mdot_soln)(node_out) >= 0)
812  ki = k_grid[i_ch][iz - 1];
813  else
814  ki = k_grid[i_ch][iz];
815  Pe = 1.0 / ((ff * dz / Dh_i + ki) * 0.5) * mdot_loc / std::abs(mdot_loc);
816  }
818 
819  // inlet, outlet, and interpolated density
820  auto rho_in = (*_rho_soln)(node_in);
821  auto rho_out = (*_rho_soln)(node_out);
822  auto rho_interp = computeInterpolatedValue(rho_out, rho_in, Pe);
823 
824  // inlet, outlet, and interpolated viscosity
825  auto mu_in = (*_mu_soln)(node_in);
826  auto mu_out = (*_mu_soln)(node_out);
827  auto mu_interp = computeInterpolatedValue(mu_out, mu_in, Pe);
828 
829  // inlet, outlet, and interpolated axial surface area
830  auto S_in = (*_S_flow_soln)(node_in);
831  auto S_out = (*_S_flow_soln)(node_out);
832  auto S_interp = computeInterpolatedValue(S_out, S_in, Pe);
833 
834  // inlet, outlet, and interpolated wetted perimeter
835  auto w_perim_in = (*_w_perim_soln)(node_in);
836  auto w_perim_out = (*_w_perim_soln)(node_out);
837  auto w_perim_interp = computeInterpolatedValue(w_perim_out, w_perim_in, Pe);
838 
839  // hydraulic diameter in the i direction
840  auto Dh_i = 4.0 * S_interp / w_perim_interp;
841 
843  if (iz == first_node)
844  {
845  PetscScalar value_vec_tt = -1.0 * _TR * alpha * (*_mdot_soln)(node_in)*dz / _dt;
846  PetscInt row_vec_tt = i_ch + _n_channels * iz_ind;
847  LibmeshPetscCall(
848  VecSetValues(_amc_time_derivative_rhs, 1, &row_vec_tt, &value_vec_tt, ADD_VALUES));
849  }
850  else
851  {
852  PetscInt row_tt = i_ch + _n_channels * iz_ind;
853  PetscInt col_tt = i_ch + _n_channels * (iz_ind - 1);
854  PetscScalar value_tt = _TR * alpha * dz / _dt;
855  LibmeshPetscCall(MatSetValues(
856  _amc_time_derivative_mat, 1, &row_tt, 1, &col_tt, &value_tt, INSERT_VALUES));
857  }
858 
859  // Adding diagonal elements
860  PetscInt row_tt = i_ch + _n_channels * iz_ind;
861  PetscInt col_tt = i_ch + _n_channels * iz_ind;
862  PetscScalar value_tt = _TR * (1.0 - alpha) * dz / _dt;
863  LibmeshPetscCall(MatSetValues(
864  _amc_time_derivative_mat, 1, &row_tt, 1, &col_tt, &value_tt, INSERT_VALUES));
865 
866  // Adding RHS elements
867  PetscScalar mdot_old_interp =
868  computeInterpolatedValue(_mdot_soln->old(node_out), _mdot_soln->old(node_in), Pe);
869  PetscScalar value_vec_tt = _TR * mdot_old_interp * dz / _dt;
870  PetscInt row_vec_tt = i_ch + _n_channels * iz_ind;
871  LibmeshPetscCall(
872  VecSetValues(_amc_time_derivative_rhs, 1, &row_vec_tt, &value_vec_tt, ADD_VALUES));
873 
875  if (iz == first_node)
876  {
877  PetscScalar value_vec_at = Utility::pow<2>((*_mdot_soln)(node_in)) / (S_in * rho_in);
878  PetscInt row_vec_at = i_ch + _n_channels * iz_ind;
879  LibmeshPetscCall(VecSetValues(
880  _amc_advective_derivative_rhs, 1, &row_vec_at, &value_vec_at, ADD_VALUES));
881  }
882  else
883  {
884  PetscInt row_at = i_ch + _n_channels * iz_ind;
885  PetscInt col_at = i_ch + _n_channels * (iz_ind - 1);
886  PetscScalar value_at = -1.0 * std::abs((*_mdot_soln)(node_in)) / (S_in * rho_in);
887  LibmeshPetscCall(MatSetValues(
888  _amc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
889  }
890 
891  // Adding diagonal elements
892  PetscInt row_at = i_ch + _n_channels * iz_ind;
893  PetscInt col_at = i_ch + _n_channels * iz_ind;
894  PetscScalar value_at = std::abs((*_mdot_soln)(node_out)) / (S_out * rho_out);
895  LibmeshPetscCall(MatSetValues(
896  _amc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
897 
899  unsigned int counter = 0;
900  unsigned int cross_index = iz; // iz-1;
901  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
902  {
903  auto chans = _subchannel_mesh.getGapChannels(i_gap);
904  unsigned int ii_ch = chans.first;
905  unsigned int jj_ch = chans.second;
906  auto * node_in_i = _subchannel_mesh.getChannelNode(ii_ch, iz - 1);
907  auto * node_in_j = _subchannel_mesh.getChannelNode(jj_ch, iz - 1);
908  auto * node_out_i = _subchannel_mesh.getChannelNode(ii_ch, iz);
909  auto * node_out_j = _subchannel_mesh.getChannelNode(jj_ch, iz);
910  auto rho_i =
911  computeInterpolatedValue((*_rho_soln)(node_out_i), (*_rho_soln)(node_in_i), Pe);
912  auto rho_j =
913  computeInterpolatedValue((*_rho_soln)(node_out_j), (*_rho_soln)(node_in_j), Pe);
914  auto S_i =
915  computeInterpolatedValue((*_S_flow_soln)(node_out_i), (*_S_flow_soln)(node_in_i), Pe);
916  auto S_j =
917  computeInterpolatedValue((*_S_flow_soln)(node_out_j), (*_S_flow_soln)(node_in_j), Pe);
918  auto u_star = 0.0;
919  // figure out donor axial velocity
920  if (_Wij(i_gap, cross_index) > 0.0)
921  {
922  if (iz == first_node)
923  {
924  u_star = (*_mdot_soln)(node_in_i) / S_i / rho_i;
925  PetscScalar value_vec_ct = -1.0 * alpha *
926  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
927  _Wij(i_gap, cross_index) * u_star;
928  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
929  LibmeshPetscCall(VecSetValues(
930  _amc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
931  }
932  else
933  {
934  PetscScalar value_ct = alpha * _subchannel_mesh.getCrossflowSign(i_ch, counter) *
935  _Wij(i_gap, cross_index) / S_i / rho_i;
936  PetscInt row_ct = i_ch + _n_channels * iz_ind;
937  PetscInt col_ct = ii_ch + _n_channels * (iz_ind - 1);
938  LibmeshPetscCall(MatSetValues(
939  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
940  }
941  PetscScalar value_ct = (1.0 - alpha) *
942  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
943  _Wij(i_gap, cross_index) / S_i / rho_i;
944  PetscInt row_ct = i_ch + _n_channels * iz_ind;
945  PetscInt col_ct = ii_ch + _n_channels * iz_ind;
946  LibmeshPetscCall(MatSetValues(
947  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
948  }
949  else if (_Wij(i_gap, cross_index) < 0.0) // _Wij=0 operations not necessary
950  {
951  if (iz == first_node)
952  {
953  u_star = (*_mdot_soln)(node_in_j) / S_j / rho_j;
954  PetscScalar value_vec_ct = -1.0 * alpha *
955  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
956  _Wij(i_gap, cross_index) * u_star;
957  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
958  LibmeshPetscCall(VecSetValues(
959  _amc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
960  }
961  else
962  {
963  PetscScalar value_ct = alpha * _subchannel_mesh.getCrossflowSign(i_ch, counter) *
964  _Wij(i_gap, cross_index) / S_j / rho_j;
965  PetscInt row_ct = i_ch + _n_channels * iz_ind;
966  PetscInt col_ct = jj_ch + _n_channels * (iz_ind - 1);
967  LibmeshPetscCall(MatSetValues(
968  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
969  }
970  PetscScalar value_ct = (1.0 - alpha) *
971  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
972  _Wij(i_gap, cross_index) / S_j / rho_j;
973  PetscInt row_ct = i_ch + _n_channels * iz_ind;
974  PetscInt col_ct = jj_ch + _n_channels * iz_ind;
975  LibmeshPetscCall(MatSetValues(
976  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
977  }
978 
979  if (iz == first_node)
980  {
981  PetscScalar value_vec_ct = -2.0 * alpha * (*_mdot_soln)(node_in)*_CT *
982  _WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
983  value_vec_ct += alpha * (*_mdot_soln)(node_in_j)*_CT * _WijPrime(i_gap, cross_index) /
984  (rho_j * S_j);
985  value_vec_ct += alpha * (*_mdot_soln)(node_in_i)*_CT * _WijPrime(i_gap, cross_index) /
986  (rho_i * S_i);
987  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
988  LibmeshPetscCall(
989  VecSetValues(_amc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
990  }
991  else
992  {
993  PetscScalar value_center_ct =
994  2.0 * alpha * _CT * _WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
995  PetscInt row_ct = i_ch + _n_channels * iz_ind;
996  PetscInt col_ct = i_ch + _n_channels * (iz_ind - 1);
997  LibmeshPetscCall(MatSetValues(
998  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_center_ct, ADD_VALUES));
999 
1000  PetscScalar value_left_ct =
1001  -1.0 * alpha * _CT * _WijPrime(i_gap, cross_index) / (rho_j * S_j);
1002  row_ct = i_ch + _n_channels * iz_ind;
1003  col_ct = jj_ch + _n_channels * (iz_ind - 1);
1004  LibmeshPetscCall(MatSetValues(
1005  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_left_ct, ADD_VALUES));
1006 
1007  PetscScalar value_right_ct =
1008  -1.0 * alpha * _CT * _WijPrime(i_gap, cross_index) / (rho_i * S_i);
1009  row_ct = i_ch + _n_channels * iz_ind;
1010  col_ct = ii_ch + _n_channels * (iz_ind - 1);
1011  LibmeshPetscCall(MatSetValues(
1012  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_right_ct, ADD_VALUES));
1013  }
1014 
1015  PetscScalar value_center_ct =
1016  2.0 * (1.0 - alpha) * _CT * _WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
1017  PetscInt row_ct = i_ch + _n_channels * iz_ind;
1018  PetscInt col_ct = i_ch + _n_channels * iz_ind;
1019  LibmeshPetscCall(MatSetValues(
1020  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_center_ct, ADD_VALUES));
1021 
1022  PetscScalar value_left_ct =
1023  -1.0 * (1.0 - alpha) * _CT * _WijPrime(i_gap, cross_index) / (rho_j * S_j);
1024  row_ct = i_ch + _n_channels * iz_ind;
1025  col_ct = jj_ch + _n_channels * iz_ind;
1026  LibmeshPetscCall(MatSetValues(
1027  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_left_ct, ADD_VALUES));
1028 
1029  PetscScalar value_right_ct =
1030  -1.0 * (1.0 - alpha) * _CT * _WijPrime(i_gap, cross_index) / (rho_i * S_i);
1031  row_ct = i_ch + _n_channels * iz_ind;
1032  col_ct = ii_ch + _n_channels * iz_ind;
1033  LibmeshPetscCall(MatSetValues(
1034  _amc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_right_ct, ADD_VALUES));
1035  counter++;
1036  }
1037 
1039  PetscScalar mdot_interp =
1040  computeInterpolatedValue((*_mdot_soln)(node_out), (*_mdot_soln)(node_in), Pe);
1041  auto Re = ((mdot_interp / S_interp) * Dh_i / mu_interp);
1042  _friction_args = FrictionStruct(i_ch, Re, S_interp, w_perim_interp);
1044  if (_ff_soln)
1045  _ff_soln->set(node_out, ff);
1047  auto ki = 0.0;
1048  if ((*_mdot_soln)(node_out) >= 0)
1049  ki = k_grid[i_ch][iz - 1];
1050  else
1051  ki = k_grid[i_ch][iz];
1052  auto coef = (ff * dz / Dh_i + ki) * 0.5 * std::abs((*_mdot_soln)(node_out)) /
1053  (S_interp * rho_interp);
1054  if (iz == first_node)
1055  {
1056  PetscScalar value_vec = -1.0 * alpha * coef * (*_mdot_soln)(node_in);
1057  PetscInt row_vec = i_ch + _n_channels * iz_ind;
1058  LibmeshPetscCall(
1059  VecSetValues(_amc_friction_force_rhs, 1, &row_vec, &value_vec, ADD_VALUES));
1060  }
1061  else
1062  {
1063  PetscInt row = i_ch + _n_channels * iz_ind;
1064  PetscInt col = i_ch + _n_channels * (iz_ind - 1);
1065  PetscScalar value = alpha * coef;
1066  LibmeshPetscCall(
1067  MatSetValues(_amc_friction_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1068  }
1069 
1070  // Adding diagonal elements
1071  PetscInt row = i_ch + _n_channels * iz_ind;
1072  PetscInt col = i_ch + _n_channels * iz_ind;
1073  PetscScalar value = (1.0 - alpha) * coef;
1074  LibmeshPetscCall(
1075  MatSetValues(_amc_friction_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1076 
1078  PetscScalar value_vec = _dir_grav * -1.0 * _g_grav * rho_interp * dz * S_interp;
1079  PetscInt row_vec = i_ch + _n_channels * iz_ind;
1080  LibmeshPetscCall(VecSetValues(_amc_gravity_rhs, 1, &row_vec, &value_vec, ADD_VALUES));
1081  }
1082  }
1084  LibmeshPetscCall(MatZeroEntries(_amc_sys_mdot_mat));
1085  LibmeshPetscCall(VecZeroEntries(_amc_sys_mdot_rhs));
1086  LibmeshPetscCall(MatAssemblyBegin(_amc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1087  LibmeshPetscCall(MatAssemblyEnd(_amc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1088  LibmeshPetscCall(MatAssemblyBegin(_amc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1089  LibmeshPetscCall(MatAssemblyEnd(_amc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1090  LibmeshPetscCall(MatAssemblyBegin(_amc_cross_derivative_mat, MAT_FINAL_ASSEMBLY));
1091  LibmeshPetscCall(MatAssemblyEnd(_amc_cross_derivative_mat, MAT_FINAL_ASSEMBLY));
1092  LibmeshPetscCall(MatAssemblyBegin(_amc_friction_force_mat, MAT_FINAL_ASSEMBLY));
1093  LibmeshPetscCall(MatAssemblyEnd(_amc_friction_force_mat, MAT_FINAL_ASSEMBLY));
1094  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1095  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1096  // Matrix
1097 #if !PETSC_VERSION_LESS_THAN(3, 15, 0)
1098  LibmeshPetscCall(
1099  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_time_derivative_mat, UNKNOWN_NONZERO_PATTERN));
1100  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1101  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1102  LibmeshPetscCall(
1103  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_advective_derivative_mat, UNKNOWN_NONZERO_PATTERN));
1104  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1105  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1106  LibmeshPetscCall(
1107  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_cross_derivative_mat, UNKNOWN_NONZERO_PATTERN));
1108  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1109  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1110  LibmeshPetscCall(
1111  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_friction_force_mat, UNKNOWN_NONZERO_PATTERN));
1112 #else
1113  LibmeshPetscCall(
1114  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_time_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1115  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1116  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1117  LibmeshPetscCall(
1118  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_advective_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1119  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1120  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1121  LibmeshPetscCall(
1122  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_cross_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1123  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1124  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1125  LibmeshPetscCall(
1126  MatAXPY(_amc_sys_mdot_mat, 1.0, _amc_friction_force_mat, DIFFERENT_NONZERO_PATTERN));
1127 #endif
1128  LibmeshPetscCall(MatAssemblyBegin(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1129  LibmeshPetscCall(MatAssemblyEnd(_amc_sys_mdot_mat, MAT_FINAL_ASSEMBLY));
1130  // RHS
1131  LibmeshPetscCall(VecAXPY(_amc_sys_mdot_rhs, 1.0, _amc_time_derivative_rhs));
1132  LibmeshPetscCall(VecAXPY(_amc_sys_mdot_rhs, 1.0, _amc_advective_derivative_rhs));
1133  LibmeshPetscCall(VecAXPY(_amc_sys_mdot_rhs, 1.0, _amc_cross_derivative_rhs));
1134  LibmeshPetscCall(VecAXPY(_amc_sys_mdot_rhs, 1.0, _amc_friction_force_rhs));
1135  LibmeshPetscCall(VecAXPY(_amc_sys_mdot_rhs, 1.0, _amc_gravity_rhs));
1136  if (_segregated_bool)
1137  {
1138  // Assembly the matrix system
1139  LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1140  _prod, *_mdot_soln, first_node, last_node, _n_channels));
1141  Vec ls;
1142  LibmeshPetscCall(VecDuplicate(_amc_sys_mdot_rhs, &ls));
1143  LibmeshPetscCall(MatMult(_amc_sys_mdot_mat, _prod, ls));
1144  LibmeshPetscCall(VecAXPY(ls, -1.0, _amc_sys_mdot_rhs));
1145  PetscScalar * xx;
1146  LibmeshPetscCall(VecGetArray(ls, &xx));
1147  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1148  {
1149  auto iz_ind = iz - first_node;
1150  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1151  {
1152  // Setting nodes
1153  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1154  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
1155 
1156  // inlet, outlet, and interpolated axial surface area
1157  auto S_in = (*_S_flow_soln)(node_in);
1158  auto S_out = (*_S_flow_soln)(node_out);
1159  auto S_interp = computeInterpolatedValue(S_out, S_in, 0.5);
1160 
1161  // Setting solutions
1162  if (S_interp != 0)
1163  {
1164  auto DP = (1 / S_interp) * xx[iz_ind * _n_channels + i_ch];
1165  _DP(i_ch, iz) = DP;
1166  if (_DP_soln)
1167  _DP_soln->set(node_out, DP);
1168  }
1169  else
1170  {
1171  auto DP = 0.0;
1172  _DP(i_ch, iz) = DP;
1173  if (_DP_soln)
1174  _DP_soln->set(node_out, DP);
1175  }
1176  }
1177  }
1178  LibmeshPetscCall(VecDestroy(&ls));
1179  }
1180  }
1181 }
Mat _amc_sys_mdot_mat
Axial momentum system matrix.
Vec _amc_gravity_rhs
Axial momentum conservation - buoyancy force No implicit matrix.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
libMesh::DenseMatrix< Real > _DP
std::unique_ptr< SolutionHandle > _S_flow_soln
Mat _amc_friction_force_mat
Axial momentum conservation - friction force.
PetscScalar computeInterpolatedValue(PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
const bool _segregated_bool
Segregated solve.
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
std::unique_ptr< SolutionHandle > _rho_soln
Mat _amc_advective_derivative_mat
Axial momentum conservation - advective (Eulerian) derivative.
std::vector< Real > _z_grid
axial location of nodes
virtual Real computeFrictionFactor(const FrictionStruct &friction_info) const =0
Computes the friction factor for the local conditions.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
static const std::string S
Definition: NS.h:167
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
const double Re
virtual const std::vector< std::vector< Real > > & getKGrid() const
Get axial cell location and value of loss coefficient.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
const MooseEnum _interpolation_scheme
The interpolation method used in constructing the systems.
const SCMFrictionClosureBase * _friction_closure
Friction closure object.
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< SolutionHandle > _DP_soln
libMesh::DenseMatrix< Real > & _Wij
static const std::string alpha
Definition: NS.h:138
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a sign for the crossflow given a subchannel index and local neighbor index.
std::unique_ptr< SolutionHandle > _SumWij_soln
Real _CT
Turbulent modeling parameter used in axial momentum equation.
Mat _amc_cross_derivative_mat
Axial momentum conservation - cross flux derivative.
std::unique_ptr< SolutionHandle > _ff_soln
struct SubChannel1PhaseProblem::FrictionStruct _friction_args
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
Mat _amc_time_derivative_mat
Axial momentum conservation - time derivative.
libMesh::DenseMatrix< Real > _WijPrime
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.

◆ computeGravityDir()

Real SubChannel1PhaseProblem::computeGravityDir ( const MooseEnum dir) const
inlineprotectedinherited

inline function that is used to define the gravity direction

Definition at line 161 of file SubChannel1PhaseProblem.h.

162  {
163  switch (dir)
164  {
165  case 0: // counter_flow
166  return 1.0;
167  case 1: // co_flow
168  return -1.0;
169  case 2: // none
170  return 0.0;
171  default:
172  mooseError(name(), ": Invalid gravity direction: expected counter_flow, co_flow, or none");
173  }
174  }
const std::string & name() const
void mooseError(Args &&... args) const

◆ computeh()

void TriSubChannel1PhaseProblem::computeh ( int  iblock)
overrideprotectedvirtual

Computes Enthalpy per channel for block iblock.

TODO: Current axial derivative is zero - check if outflow conditions may make a difference

Implements SubChannel1PhaseProblem.

Definition at line 325 of file TriSubChannel1PhaseProblem.C.

326 {
327  unsigned int last_node = (iblock + 1) * _block_size;
328  unsigned int first_node = iblock * _block_size + 1;
329  const Real & wire_lead_length = _tri_sch_mesh.getWireLeadLength();
330  const Real & wire_diameter = _tri_sch_mesh.getWireDiameter();
331  const Real & pitch = _subchannel_mesh.getPitch();
332  const Real & pin_diameter = _subchannel_mesh.getPinDiameter();
333 
334  if (iblock == 0)
335  {
336  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
337  {
338  auto * node = _subchannel_mesh.getChannelNode(i_ch, 0);
339  auto h_out = _fp->h_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node));
340  if (h_out < 0)
341  {
342  mooseError(
343  name(), " : Calculation of negative Enthalpy h_out = : ", h_out, " Axial Level= : ", 0);
344  }
345  _h_soln->set(node, h_out);
346  }
347  }
348 
349  if (!_implicit_bool)
350  {
351  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
352  {
353  auto z_grid = _subchannel_mesh.getZGrid();
354  auto dz = z_grid[iz] - z_grid[iz - 1];
355  // Calculation of average mass flux of all periphery subchannels
356  Real edge_flux_ave = 0.0;
357  Real mdot_sum = 0.0;
358  Real si_sum = 0.0;
359  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
360  {
361  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
362  if (subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER)
363  {
364  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
365  auto Si = (*_S_flow_soln)(node_in);
366  auto mdot_in = (*_mdot_soln)(node_in);
367  mdot_sum = mdot_sum + mdot_in;
368  si_sum = si_sum + Si;
369  }
370  }
371  edge_flux_ave = mdot_sum / si_sum;
372 
373  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
374  {
375  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
376  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
377  auto mdot_in = (*_mdot_soln)(node_in);
378  auto h_in = (*_h_soln)(node_in); // J/kg
379  auto volume = dz * (*_S_flow_soln)(node_in);
380  auto mdot_out = (*_mdot_soln)(node_out);
381  auto h_out = 0.0;
382  Real sumWijh = 0.0;
383  Real sumWijPrimeDhij = 0.0;
384  Real sweep_enthalpy = 0.0;
385  Real e_cond = 0.0;
386 
387  // Calculate added enthalpy from heatflux (Pin, Duct)
388  Real added_enthalpy = computeAddedHeatPin(i_ch, iz);
389  added_enthalpy += computeAddedHeatDuct(i_ch, iz);
390 
391  // Calculate net sum of enthalpy into/out-of channel i from channels j around i
392  // (Turbulent diffusion, Diversion Crossflow, Sweep flow Enthalpy, Radial heat conduction)
393  unsigned int counter = 0;
394  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
395  {
396  auto chans = _subchannel_mesh.getGapChannels(i_gap);
397  auto gap = _subchannel_mesh.getGapWidth(iz, i_gap);
398  auto Sij = dz * gap;
399  unsigned int ii_ch = chans.first; // the first subchannel next to gap i_gap
400  unsigned int jj_ch = chans.second; // the second subchannel next to gap i_gap
401  auto * node_in_i = _subchannel_mesh.getChannelNode(ii_ch, iz - 1);
402  auto * node_in_j = _subchannel_mesh.getChannelNode(jj_ch, iz - 1);
403  auto subch_type_i = _subchannel_mesh.getSubchannelType(ii_ch);
404  auto subch_type_j = _subchannel_mesh.getSubchannelType(jj_ch);
405  // Define donor enthalpy
406  auto h_star = 0.0;
407  if (_Wij(i_gap, iz) > 0.0)
408  h_star = (*_h_soln)(node_in_i);
409  else if (_Wij(i_gap, iz) < 0.0)
410  h_star = (*_h_soln)(node_in_j);
411  // Diversion crossflow
412  // take care of the sign by applying the map, use donor cell
413  sumWijh += _subchannel_mesh.getCrossflowSign(i_ch, counter) * _Wij(i_gap, iz) * h_star;
414  counter++;
415  // SWEEP FLOW is calculated if i_gap is located in the periphery
416  // and we have a wire-wrap (if i_gap is in the periphery then i_ch is in the periphery)
417  // There are two gaps per periphery subchannel that this is true.
418  if ((subch_type_i == EChannelType::CORNER || subch_type_i == EChannelType::EDGE) &&
419  (subch_type_j == EChannelType::CORNER || subch_type_j == EChannelType::EDGE) &&
420  (wire_lead_length != 0) && (wire_diameter != 0))
421  {
422  // donor subchannel and node of sweep flow. The donor subchannel is the subchannel next
423  // to i_ch that sweep flow, flows from and into i_ch
424  auto sweep_donor = _tri_sch_mesh.getSweepFlowChans(i_ch).first;
425  auto * node_sweep_donor = _subchannel_mesh.getChannelNode(sweep_donor, iz - 1);
426  // if one of the neighbor subchannels of the periphery gap is the donor subchannel
427  //(the other would be the i_ch) sweep enthalpy flows into i_ch
428  if ((ii_ch == sweep_donor) || (jj_ch == sweep_donor))
429  {
430  sweep_enthalpy += computeSweepFlowMixingParameter(i_gap, iz) * edge_flux_ave * Sij *
431  (*_h_soln)(node_sweep_donor);
432  }
433  // else sweep enthalpy flows out of i_ch
434  else
435  {
436  sweep_enthalpy -= computeSweepFlowMixingParameter(i_gap, iz) * edge_flux_ave * Sij *
437  (*_h_soln)(node_in);
438  }
439  }
440  // Inner gap
441  // Turbulent Diffusion
442  else
443  {
444  sumWijPrimeDhij +=
445  _WijPrime(i_gap, iz) * (2 * h_in - (*_h_soln)(node_in_j) - (*_h_soln)(node_in_i));
446  }
447 
448  // compute the radial heat conduction through the gaps
449  Real dist_ij = pitch;
450 
451  if (subch_type_i == EChannelType::EDGE && subch_type_j == EChannelType::EDGE)
452  {
453  dist_ij = pitch;
454  }
455  else if ((subch_type_i == EChannelType::CORNER && subch_type_j == EChannelType::EDGE) ||
456  (subch_type_i == EChannelType::EDGE && subch_type_j == EChannelType::CORNER))
457  {
458  dist_ij = pitch;
459  }
460  else
461  {
462  dist_ij = pitch / std::sqrt(3);
463  }
464 
465  auto thcon_i = _fp->k_from_p_T((*_P_soln)(node_in_i) + _P_out, (*_T_soln)(node_in_i));
466  auto thcon_j = _fp->k_from_p_T((*_P_soln)(node_in_j) + _P_out, (*_T_soln)(node_in_j));
467  auto shape_factor =
468  0.66 * (pitch / pin_diameter) *
469  std::pow((_subchannel_mesh.getGapWidth(iz, i_gap) / pin_diameter), -0.3);
470  if (ii_ch == i_ch)
471  {
472  e_cond += 0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
473  ((*_T_soln)(node_in_j) - (*_T_soln)(node_in_i)) / dist_ij;
474  }
475  else
476  {
477  e_cond += -0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
478  ((*_T_soln)(node_in_j) - (*_T_soln)(node_in_i)) / dist_ij;
479  }
480  }
481 
482  // compute the axial heat conduction between current and lower axial node
483  auto * node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz);
484  auto * node_in_j = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
485  auto thcon_i = _fp->k_from_p_T((*_P_soln)(node_in_i) + _P_out, (*_T_soln)(node_in_i));
486  auto thcon_j = _fp->k_from_p_T((*_P_soln)(node_in_j) + _P_out, (*_T_soln)(node_in_j));
487  auto Si = (*_S_flow_soln)(node_in_i);
488  auto dist_ij = z_grid[iz] - z_grid[iz - 1];
489 
490  e_cond += 0.5 * (thcon_i + thcon_j) * Si * ((*_T_soln)(node_in_j) - (*_T_soln)(node_in_i)) /
491  dist_ij;
492 
493  unsigned int nz = _subchannel_mesh.getNumOfAxialCells();
494  // compute the axial heat conduction between current and upper axial node
495  if (iz < nz)
496  {
497  auto * node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz);
498  auto * node_in_j = _subchannel_mesh.getChannelNode(i_ch, iz + 1);
499  auto thcon_i = _fp->k_from_p_T((*_P_soln)(node_in_i) + _P_out, (*_T_soln)(node_in_i));
500  auto thcon_j = _fp->k_from_p_T((*_P_soln)(node_in_j) + _P_out, (*_T_soln)(node_in_j));
501  auto Si = (*_S_flow_soln)(node_in_i);
502  auto dist_ij = z_grid[iz + 1] - z_grid[iz];
503  e_cond += 0.5 * (thcon_i + thcon_j) * Si *
504  ((*_T_soln)(node_in_j) - (*_T_soln)(node_in_i)) / dist_ij;
505  }
506 
507  // end of radial heat conduction calc.
508  h_out =
509  (mdot_in * h_in - sumWijh - sumWijPrimeDhij + added_enthalpy + e_cond + sweep_enthalpy +
510  _TR * _rho_soln->old(node_out) * _h_soln->old(node_out) * volume / _dt) /
511  (mdot_out + _TR * (*_rho_soln)(node_out)*volume / _dt);
512  if (h_out < 0)
513  {
514  mooseError(name(),
515  " : Calculation of negative Enthalpy h_out = : ",
516  h_out,
517  " Axial Level= : ",
518  iz);
519  }
520  _h_soln->set(node_out, h_out); // J/kg
521  }
522  }
523  }
524  else
525  {
526  LibmeshPetscCall(MatZeroEntries(_hc_time_derivative_mat));
527  LibmeshPetscCall(MatZeroEntries(_hc_advective_derivative_mat));
528  LibmeshPetscCall(MatZeroEntries(_hc_cross_derivative_mat));
529  LibmeshPetscCall(MatZeroEntries(_hc_axial_heat_conduction_mat));
530  LibmeshPetscCall(MatZeroEntries(_hc_radial_heat_conduction_mat));
531  LibmeshPetscCall(MatZeroEntries(_hc_sweep_enthalpy_mat));
532 
533  LibmeshPetscCall(VecZeroEntries(_hc_time_derivative_rhs));
534  LibmeshPetscCall(VecZeroEntries(_hc_advective_derivative_rhs));
535  LibmeshPetscCall(VecZeroEntries(_hc_cross_derivative_rhs));
536  LibmeshPetscCall(VecZeroEntries(_hc_added_heat_rhs));
537  LibmeshPetscCall(VecZeroEntries(_hc_axial_heat_conduction_rhs));
538  LibmeshPetscCall(VecZeroEntries(_hc_radial_heat_conduction_rhs));
539  LibmeshPetscCall(VecZeroEntries(_hc_sweep_enthalpy_rhs));
540 
541  LibmeshPetscCall(MatZeroEntries(_hc_sys_h_mat));
542  LibmeshPetscCall(VecZeroEntries(_hc_sys_h_rhs));
543 
544  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
545  {
546  auto dz = _z_grid[iz] - _z_grid[iz - 1];
548  auto pin_diameter = _subchannel_mesh.getPinDiameter();
549  auto iz_ind = iz - first_node;
550 
551  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
552  {
553  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
554  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
555  auto S_in = (*_S_flow_soln)(node_in);
556  auto S_out = (*_S_flow_soln)(node_out);
557  auto S_interp = computeInterpolatedValue(S_out, S_in, 0.5);
558  auto volume = dz * S_interp;
559 
560  PetscScalar Pe = 0.5;
561  if (_interpolation_scheme == 3)
562  {
563  // Compute the Peclet number
564  auto w_perim_in = (*_w_perim_soln)(node_in);
565  auto w_perim_out = (*_w_perim_soln)(node_out);
566  auto w_perim_interp = this->computeInterpolatedValue(w_perim_out, w_perim_in, 0.5);
567  auto K_in = _fp->k_from_p_T((*_P_soln)(node_in) + _P_out, (*_T_soln)(node_in));
568  auto K_out = _fp->k_from_p_T((*_P_soln)(node_out) + _P_out, (*_T_soln)(node_out));
569  auto K = this->computeInterpolatedValue(K_out, K_in, 0.5);
570  auto cp_in = _fp->cp_from_p_T((*_P_soln)(node_in) + _P_out, (*_T_soln)(node_in));
571  auto cp_out = _fp->cp_from_p_T((*_P_soln)(node_out) + _P_out, (*_T_soln)(node_out));
572  auto cp = this->computeInterpolatedValue(cp_out, cp_in, 0.5);
573  auto mdot_loc =
574  this->computeInterpolatedValue((*_mdot_soln)(node_out), (*_mdot_soln)(node_in), 0.5);
575  // hydraulic diameter in the i direction
576  auto Dh_i = 4.0 * S_interp / w_perim_interp;
577  Pe = mdot_loc * Dh_i * cp / (K * S_interp) * (mdot_loc / std::abs(mdot_loc));
578  }
580 
581  // Time derivative term
582  if (iz == first_node)
583  {
584  PetscScalar value_vec_tt =
585  -1.0 * _TR * alpha * (*_rho_soln)(node_in) * (*_h_soln)(node_in)*volume / _dt;
586  PetscInt row_vec_tt = i_ch + _n_channels * iz_ind;
587  LibmeshPetscCall(
588  VecSetValues(_hc_time_derivative_rhs, 1, &row_vec_tt, &value_vec_tt, ADD_VALUES));
589  }
590  else
591  {
592  PetscInt row_tt = i_ch + _n_channels * iz_ind;
593  PetscInt col_tt = i_ch + _n_channels * (iz_ind - 1);
594  PetscScalar value_tt = _TR * alpha * (*_rho_soln)(node_in)*volume / _dt;
595  LibmeshPetscCall(MatSetValues(
596  _hc_time_derivative_mat, 1, &row_tt, 1, &col_tt, &value_tt, INSERT_VALUES));
597  }
598 
599  // Adding diagonal elements
600  PetscInt row_tt = i_ch + _n_channels * iz_ind;
601  PetscInt col_tt = i_ch + _n_channels * iz_ind;
602  PetscScalar value_tt = _TR * (1.0 - alpha) * (*_rho_soln)(node_out)*volume / _dt;
603  LibmeshPetscCall(MatSetValues(
604  _hc_time_derivative_mat, 1, &row_tt, 1, &col_tt, &value_tt, INSERT_VALUES));
605 
606  // Adding RHS elements
607  PetscScalar rho_old_interp =
608  computeInterpolatedValue(_rho_soln->old(node_out), _rho_soln->old(node_in), Pe);
609  PetscScalar h_old_interp =
610  computeInterpolatedValue(_h_soln->old(node_out), _h_soln->old(node_in), Pe);
611  PetscScalar value_vec_tt = _TR * rho_old_interp * h_old_interp * volume / _dt;
612  PetscInt row_vec_tt = i_ch + _n_channels * iz_ind;
613  LibmeshPetscCall(
614  VecSetValues(_hc_time_derivative_rhs, 1, &row_vec_tt, &value_vec_tt, ADD_VALUES));
615 
616  // Advective derivative term
617  if (iz == first_node)
618  {
619  PetscInt row_at = i_ch + _n_channels * iz_ind;
620  PetscScalar value_at = alpha * (*_mdot_soln)(node_in) * (*_h_soln)(node_in);
621  LibmeshPetscCall(
622  VecSetValues(_hc_advective_derivative_rhs, 1, &row_at, &value_at, ADD_VALUES));
623 
624  value_at = alpha * (*_mdot_soln)(node_out) - (1 - alpha) * (*_mdot_soln)(node_in);
625  PetscInt col_at = i_ch + _n_channels * iz_ind;
626  LibmeshPetscCall(MatSetValues(
627  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
628 
629  value_at = (1 - alpha) * (*_mdot_soln)(node_out);
630  col_at = i_ch + _n_channels * (iz_ind + 1);
631  LibmeshPetscCall(MatSetValues(
632  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
633  }
634  else if (iz == last_node)
635  {
636  PetscInt row_at = i_ch + _n_channels * iz_ind;
637  PetscScalar value_at = 1.0 * (*_mdot_soln)(node_out);
638  PetscInt col_at = i_ch + _n_channels * iz_ind;
639  LibmeshPetscCall(MatSetValues(
640  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
641 
642  value_at = -1.0 * (*_mdot_soln)(node_in);
643  col_at = i_ch + _n_channels * (iz_ind - 1);
644  LibmeshPetscCall(MatSetValues(
645  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
646  }
647  else
648  {
649  PetscInt row_at = i_ch + _n_channels * iz_ind;
650  PetscInt col_at;
651 
652  PetscScalar value_at = -alpha * (*_mdot_soln)(node_in);
653  col_at = i_ch + _n_channels * (iz_ind - 1);
654  LibmeshPetscCall(MatSetValues(
655  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
656 
657  value_at = alpha * (*_mdot_soln)(node_out) - (1 - alpha) * (*_mdot_soln)(node_in);
658  col_at = i_ch + _n_channels * iz_ind;
659  LibmeshPetscCall(MatSetValues(
660  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
661 
662  value_at = (1 - alpha) * (*_mdot_soln)(node_out);
663  col_at = i_ch + _n_channels * (iz_ind + 1);
664  LibmeshPetscCall(MatSetValues(
665  _hc_advective_derivative_mat, 1, &row_at, 1, &col_at, &value_at, ADD_VALUES));
666  }
667 
668  // Axial heat conduction
669  auto * node_center = _subchannel_mesh.getChannelNode(i_ch, iz);
670  auto K_center = _fp->k_from_p_T((*_P_soln)(node_center) + _P_out, (*_T_soln)(node_center));
671  auto cp_center =
672  _fp->cp_from_p_T((*_P_soln)(node_center) + _P_out, (*_T_soln)(node_center));
673  auto diff_center = K_center / (cp_center + 1e-15);
674 
675  if (iz == first_node)
676  {
677  auto * node_top = _subchannel_mesh.getChannelNode(i_ch, iz + 1);
678  auto * node_bottom = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
679  auto K_bottom =
680  _fp->k_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
681  auto K_top = _fp->k_from_p_T((*_P_soln)(node_top) + _P_out, (*_T_soln)(node_top));
682  auto cp_bottom =
683  _fp->cp_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
684  auto cp_top = _fp->cp_from_p_T((*_P_soln)(node_top) + _P_out, (*_T_soln)(node_top));
685  auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
686  auto diff_top = K_top / (cp_top + 1e-15);
687 
688  auto dz_up = _z_grid[iz + 1] - _z_grid[iz];
689  auto dz_down = _z_grid[iz] - _z_grid[iz - 1];
690  auto S_up =
691  computeInterpolatedValue((*_S_flow_soln)(node_top), (*_S_flow_soln)(node_center));
692  auto S_down =
693  computeInterpolatedValue((*_S_flow_soln)(node_center), (*_S_flow_soln)(node_bottom));
694  auto diff_up = computeInterpolatedValue(diff_top, diff_center);
695  auto diff_down = computeInterpolatedValue(diff_center, diff_bottom);
696 
697  // Diagonal value
698  PetscInt row_at = i_ch + _n_channels * iz_ind;
699  PetscInt col_at = i_ch + _n_channels * iz_ind;
700  PetscScalar value_at = diff_up * S_up / dz_up + diff_down * S_down / dz_down;
701  LibmeshPetscCall(MatSetValues(
702  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
703 
704  // Bottom value
705  value_at = 1.0 * diff_down * S_down / dz_down * (*_h_soln)(node_bottom);
706  LibmeshPetscCall(
707  VecSetValues(_hc_axial_heat_conduction_rhs, 1, &row_at, &value_at, ADD_VALUES));
708 
709  // Top value
710  col_at = i_ch + _n_channels * (iz_ind + 1);
711  value_at = -diff_up * S_up / dz_up;
712  LibmeshPetscCall(MatSetValues(
713  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
714  }
715  else if (iz == last_node)
716  {
717  auto * node_bottom = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
718  auto K_bottom =
719  _fp->k_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
720  auto cp_bottom =
721  _fp->cp_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
722  auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
723 
724  auto dz_down = _z_grid[iz] - _z_grid[iz - 1];
725  auto S_down = 0.5 * ((*_S_flow_soln)(node_center) + (*_S_flow_soln)(node_bottom));
726  auto diff_down = 0.5 * (diff_center + diff_bottom);
727 
728  // Diagonal value
729  PetscInt row_at = i_ch + _n_channels * iz_ind;
730  PetscInt col_at = i_ch + _n_channels * iz_ind;
731  PetscScalar value_at = diff_down * S_down / dz_down;
732  LibmeshPetscCall(MatSetValues(
733  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
734 
735  // Bottom value
736  col_at = i_ch + _n_channels * (iz_ind - 1);
737  value_at = -diff_down * S_down / dz_down;
738  LibmeshPetscCall(MatSetValues(
739  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
740 
741  // Outflow derivative
743  // value_at = -1.0 * (*_mdot_soln)(node_center) * (*_h_soln)(node_center);
744  // VecSetValues(_hc_axial_heat_conduction_rhs, 1, &row_at, &value_at, ADD_VALUES);
745  }
746  else
747  {
748  auto * node_top = _subchannel_mesh.getChannelNode(i_ch, iz + 1);
749  auto * node_bottom = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
750  auto K_bottom =
751  _fp->k_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
752  auto K_top = _fp->k_from_p_T((*_P_soln)(node_top) + _P_out, (*_T_soln)(node_top));
753  auto cp_bottom =
754  _fp->cp_from_p_T((*_P_soln)(node_bottom) + _P_out, (*_T_soln)(node_bottom));
755  auto cp_top = _fp->cp_from_p_T((*_P_soln)(node_top) + _P_out, (*_T_soln)(node_top));
756  auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
757  auto diff_top = K_top / (cp_top + 1e-15);
758 
759  auto dz_up = _z_grid[iz + 1] - _z_grid[iz];
760  auto dz_down = _z_grid[iz] - _z_grid[iz - 1];
761  auto S_up =
762  computeInterpolatedValue((*_S_flow_soln)(node_top), (*_S_flow_soln)(node_center));
763  auto S_down =
764  computeInterpolatedValue((*_S_flow_soln)(node_center), (*_S_flow_soln)(node_bottom));
765  auto diff_up = computeInterpolatedValue(diff_top, diff_center);
766  auto diff_down = computeInterpolatedValue(diff_center, diff_bottom);
767 
768  // Diagonal value
769  PetscInt row_at = i_ch + _n_channels * iz_ind;
770  PetscInt col_at = i_ch + _n_channels * iz_ind;
771  PetscScalar value_at = diff_up * S_up / dz_up + diff_down * S_down / dz_down;
772  LibmeshPetscCall(MatSetValues(
773  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
774 
775  // Bottom value
776  col_at = i_ch + _n_channels * (iz_ind - 1);
777  value_at = -diff_down * S_down / dz_down;
778  LibmeshPetscCall(MatSetValues(
779  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
780 
781  // Top value
782  col_at = i_ch + _n_channels * (iz_ind + 1);
783  value_at = -diff_up * S_up / dz_up;
784  LibmeshPetscCall(MatSetValues(
785  _hc_axial_heat_conduction_mat, 1, &row_at, 1, &col_at, &value_at, INSERT_VALUES));
786  }
787 
788  // Radial Terms
789  unsigned int counter = 0;
790  unsigned int cross_index = iz;
791  // Real radial_heat_conduction(0.0);
792  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
793  {
794  auto chans = _subchannel_mesh.getGapChannels(i_gap);
795  unsigned int ii_ch = chans.first;
796  unsigned int jj_ch = chans.second;
797  auto * node_in_i = _subchannel_mesh.getChannelNode(ii_ch, iz - 1);
798  auto * node_in_j = _subchannel_mesh.getChannelNode(jj_ch, iz - 1);
799  PetscScalar h_star;
800  // figure out donor axial velocity
801  if (_Wij(i_gap, cross_index) > 0.0)
802  {
803  if (iz == first_node)
804  {
805  h_star = (*_h_soln)(node_in_i);
806  PetscScalar value_vec_ct = -1.0 * alpha *
807  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
808  _Wij(i_gap, cross_index) * h_star;
809  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
810  LibmeshPetscCall(VecSetValues(
811  _hc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
812  }
813  else
814  {
815  PetscScalar value_ct = alpha * _subchannel_mesh.getCrossflowSign(i_ch, counter) *
816  _Wij(i_gap, cross_index);
817  PetscInt row_ct = i_ch + _n_channels * iz_ind;
818  PetscInt col_ct = ii_ch + _n_channels * (iz_ind - 1);
819  LibmeshPetscCall(MatSetValues(
820  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
821  }
822  PetscScalar value_ct = (1.0 - alpha) *
823  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
824  _Wij(i_gap, cross_index);
825  PetscInt row_ct = i_ch + _n_channels * iz_ind;
826  PetscInt col_ct = ii_ch + _n_channels * iz_ind;
827  LibmeshPetscCall(MatSetValues(
828  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
829  }
830  else if (_Wij(i_gap, cross_index) < 0.0) // _Wij=0 operations not necessary
831  {
832  if (iz == first_node)
833  {
834  h_star = (*_h_soln)(node_in_j);
835  PetscScalar value_vec_ct = -1.0 * alpha *
836  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
837  _Wij(i_gap, cross_index) * h_star;
838  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
839  LibmeshPetscCall(VecSetValues(
840  _hc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
841  }
842  else
843  {
844  PetscScalar value_ct = alpha * _subchannel_mesh.getCrossflowSign(i_ch, counter) *
845  _Wij(i_gap, cross_index);
846  PetscInt row_ct = i_ch + _n_channels * iz_ind;
847  PetscInt col_ct = jj_ch + _n_channels * (iz_ind - 1);
848  LibmeshPetscCall(MatSetValues(
849  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
850  }
851  PetscScalar value_ct = (1.0 - alpha) *
852  _subchannel_mesh.getCrossflowSign(i_ch, counter) *
853  _Wij(i_gap, cross_index);
854  PetscInt row_ct = i_ch + _n_channels * iz_ind;
855  PetscInt col_ct = jj_ch + _n_channels * iz_ind;
856  LibmeshPetscCall(MatSetValues(
857  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_ct, ADD_VALUES));
858  }
859 
860  // Turbulent cross flows
861  if (iz == first_node)
862  {
863  PetscScalar value_vec_ct =
864  -2.0 * alpha * (*_h_soln)(node_in)*_WijPrime(i_gap, cross_index);
865  value_vec_ct += alpha * (*_h_soln)(node_in_j)*_WijPrime(i_gap, cross_index);
866  value_vec_ct += alpha * (*_h_soln)(node_in_i)*_WijPrime(i_gap, cross_index);
867  PetscInt row_vec_ct = i_ch + _n_channels * iz_ind;
868  LibmeshPetscCall(
869  VecSetValues(_hc_cross_derivative_rhs, 1, &row_vec_ct, &value_vec_ct, ADD_VALUES));
870  }
871  else
872  {
873  PetscScalar value_center_ct = 2.0 * alpha * _WijPrime(i_gap, cross_index);
874  PetscInt row_ct = i_ch + _n_channels * iz_ind;
875  PetscInt col_ct = i_ch + _n_channels * (iz_ind - 1);
876  LibmeshPetscCall(MatSetValues(
877  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_center_ct, ADD_VALUES));
878 
879  PetscScalar value_left_ct = -1.0 * alpha * _WijPrime(i_gap, cross_index);
880  row_ct = i_ch + _n_channels * iz_ind;
881  col_ct = jj_ch + _n_channels * (iz_ind - 1);
882  LibmeshPetscCall(MatSetValues(
883  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_left_ct, ADD_VALUES));
884 
885  PetscScalar value_right_ct = -1.0 * alpha * _WijPrime(i_gap, cross_index);
886  row_ct = i_ch + _n_channels * iz_ind;
887  col_ct = ii_ch + _n_channels * (iz_ind - 1);
888  LibmeshPetscCall(MatSetValues(
889  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_right_ct, ADD_VALUES));
890  }
891  PetscScalar value_center_ct = 2.0 * (1.0 - alpha) * _WijPrime(i_gap, cross_index);
892  PetscInt row_ct = i_ch + _n_channels * iz_ind;
893  PetscInt col_ct = i_ch + _n_channels * iz_ind;
894  LibmeshPetscCall(MatSetValues(
895  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_center_ct, ADD_VALUES));
896 
897  PetscScalar value_left_ct = -1.0 * (1.0 - alpha) * _WijPrime(i_gap, cross_index);
898  row_ct = i_ch + _n_channels * iz_ind;
899  col_ct = jj_ch + _n_channels * iz_ind;
900  LibmeshPetscCall(MatSetValues(
901  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_left_ct, ADD_VALUES));
902 
903  PetscScalar value_right_ct = -1.0 * (1.0 - alpha) * _WijPrime(i_gap, cross_index);
904  row_ct = i_ch + _n_channels * iz_ind;
905  col_ct = ii_ch + _n_channels * iz_ind;
906  LibmeshPetscCall(MatSetValues(
907  _hc_cross_derivative_mat, 1, &row_ct, 1, &col_ct, &value_right_ct, ADD_VALUES));
908 
909  // Radial heat conduction
910  auto subch_type_i = _subchannel_mesh.getSubchannelType(ii_ch);
911  auto subch_type_j = _subchannel_mesh.getSubchannelType(jj_ch);
912  Real dist_ij = pitch;
913 
914  if (subch_type_i == EChannelType::EDGE && subch_type_j == EChannelType::EDGE)
915  {
916  dist_ij = pitch;
917  }
918  else if ((subch_type_i == EChannelType::CORNER && subch_type_j == EChannelType::EDGE) ||
919  (subch_type_i == EChannelType::EDGE && subch_type_j == EChannelType::CORNER))
920  {
921  dist_ij = pitch;
922  }
923  else
924  {
925  dist_ij = pitch / std::sqrt(3);
926  }
927 
928  auto Sij = dz * _subchannel_mesh.getGapWidth(iz, i_gap);
929  auto K_i = _fp->k_from_p_T((*_P_soln)(node_in_i) + _P_out, (*_T_soln)(node_in_i));
930  auto K_j = _fp->k_from_p_T((*_P_soln)(node_in_j) + _P_out, (*_T_soln)(node_in_j));
931  auto cp_i = _fp->cp_from_p_T((*_P_soln)(node_in_i) + _P_out, (*_T_soln)(node_in_i));
932  auto cp_j = _fp->cp_from_p_T((*_P_soln)(node_in_j) + _P_out, (*_T_soln)(node_in_j));
933  auto A_i = K_i / cp_i;
934  auto A_j = K_j / cp_j;
935  auto harm_A = 2.0 * A_i * A_j / (A_i + A_j);
936  auto shape_factor =
937  0.66 * (pitch / pin_diameter) *
938  std::pow((_subchannel_mesh.getGapWidth(iz, i_gap) / pin_diameter), -0.3);
939  // auto base_value = 0.5 * (A_i + A_j) * Sij * shape_factor / dist_ij;
940  auto base_value = harm_A * shape_factor * Sij / dist_ij;
941  auto neg_base_value = -1.0 * base_value;
942 
943  row_ct = ii_ch + _n_channels * iz_ind;
944  col_ct = ii_ch + _n_channels * iz_ind;
945  LibmeshPetscCall(MatSetValues(
946  _hc_radial_heat_conduction_mat, 1, &row_ct, 1, &col_ct, &base_value, ADD_VALUES));
947 
948  row_ct = jj_ch + _n_channels * iz_ind;
949  col_ct = jj_ch + _n_channels * iz_ind;
950  LibmeshPetscCall(MatSetValues(
951  _hc_radial_heat_conduction_mat, 1, &row_ct, 1, &col_ct, &base_value, ADD_VALUES));
952 
953  row_ct = ii_ch + _n_channels * iz_ind;
954  col_ct = jj_ch + _n_channels * iz_ind;
955  LibmeshPetscCall(MatSetValues(
956  _hc_radial_heat_conduction_mat, 1, &row_ct, 1, &col_ct, &neg_base_value, ADD_VALUES));
957 
958  row_ct = jj_ch + _n_channels * iz_ind;
959  col_ct = ii_ch + _n_channels * iz_ind;
960  LibmeshPetscCall(MatSetValues(
961  _hc_radial_heat_conduction_mat, 1, &row_ct, 1, &col_ct, &neg_base_value, ADD_VALUES));
962  counter++;
963  }
964 
965  // Compute the sweep flow enthalpy change
966  // Calculation of average mass flux of all periphery subchannels
967  Real edge_flux_ave = 0.0;
968  Real mdot_sum = 0.0;
969  Real si_sum = 0.0;
970  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
971  {
972  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
973  if (subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER)
974  {
975  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
976  auto Si = (*_S_flow_soln)(node_in);
977  auto mdot_in = (*_mdot_soln)(node_in);
978  mdot_sum = mdot_sum + mdot_in;
979  si_sum = si_sum + Si;
980  }
981  }
982  edge_flux_ave = mdot_sum / si_sum;
983  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
984  PetscScalar sweep_enthalpy = 0.0;
985  if ((subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER) &&
986  (wire_diameter != 0.0) && (wire_lead_length != 0.0))
987  {
988  auto beta_in = std::numeric_limits<double>::quiet_NaN();
989  auto beta_out = std::numeric_limits<double>::quiet_NaN();
990  // donor sweep channel for i_ch
991  auto sweep_donor = _tri_sch_mesh.getSweepFlowChans(i_ch).first;
992  auto * node_sweep_donor = _subchannel_mesh.getChannelNode(sweep_donor, iz - 1);
993  // Calculation of turbulent mixing parameter
994  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
995  {
996  auto chans = _subchannel_mesh.getGapChannels(i_gap);
997  unsigned int ii_ch = chans.first;
998  unsigned int jj_ch = chans.second;
999  auto subch_type_i = _subchannel_mesh.getSubchannelType(ii_ch);
1000  auto subch_type_j = _subchannel_mesh.getSubchannelType(jj_ch);
1001  if ((subch_type_i == EChannelType::CORNER || subch_type_i == EChannelType::EDGE) &&
1002  (subch_type_j == EChannelType::CORNER || subch_type_j == EChannelType::EDGE))
1003  {
1004  if ((ii_ch == sweep_donor) || (jj_ch == sweep_donor))
1005  {
1006  beta_in = computeSweepFlowMixingParameter(i_gap, iz);
1007  }
1008  else
1009  {
1010  beta_out = computeSweepFlowMixingParameter(i_gap, iz);
1011  }
1012  }
1013  }
1014  // Abort execution if required values are unset
1015  mooseAssert(!std::isnan(beta_in),
1016  "beta_in was not set. Check gap logic for i_ch = " + std::to_string(i_ch) +
1017  ", iz = " + std::to_string(iz));
1018  mooseAssert(!std::isnan(beta_out),
1019  "beta_out was not set. Check gap logic for i_ch = " + std::to_string(i_ch) +
1020  ", iz = " + std::to_string(iz));
1021 
1022  auto gap = _tri_sch_mesh.getDuctToPinGap();
1023  auto Sij = dz * gap;
1024  auto wsweep_in = edge_flux_ave * beta_in * Sij;
1025  auto wsweep_out = edge_flux_ave * beta_out * Sij;
1026  auto sweep_hin = (*_h_soln)(node_sweep_donor);
1027  auto sweep_hout = (*_h_soln)(node_in);
1028  sweep_enthalpy = (wsweep_in * sweep_hin - wsweep_out * sweep_hout);
1029 
1030  if (iz == first_node)
1031  {
1032  PetscInt row_sh = i_ch + _n_channels * iz_ind;
1033  PetscScalar value_hs = -sweep_enthalpy;
1034  LibmeshPetscCall(
1035  VecSetValues(_hc_sweep_enthalpy_rhs, 1, &row_sh, &value_hs, ADD_VALUES));
1036  }
1037  else
1038  {
1039  // coefficient of sweep_hin
1040  PetscInt row_sh = i_ch + _n_channels * (iz_ind - 1);
1041  PetscInt col_sh = i_ch + _n_channels * (iz_ind - 1);
1042  LibmeshPetscCall(MatSetValues(
1043  _hc_sweep_enthalpy_mat, 1, &row_sh, 1, &col_sh, &wsweep_out, ADD_VALUES));
1044  PetscInt col_sh_l = sweep_donor + _n_channels * (iz_ind - 1);
1045  PetscScalar neg_sweep_in = -1.0 * wsweep_in;
1046  // coefficient of sweep_hout
1047  LibmeshPetscCall(MatSetValues(
1048  _hc_sweep_enthalpy_mat, 1, &row_sh, 1, &col_sh_l, &(neg_sweep_in), ADD_VALUES));
1049  }
1050  }
1051 
1052  // Add heat enthalpy from pin and/or duct
1053  PetscScalar added_enthalpy = computeAddedHeatPin(i_ch, iz);
1054  added_enthalpy += computeAddedHeatDuct(i_ch, iz);
1055  PetscInt row_vec_ht = i_ch + _n_channels * iz_ind;
1056  LibmeshPetscCall(
1057  VecSetValues(_hc_added_heat_rhs, 1, &row_vec_ht, &added_enthalpy, ADD_VALUES));
1058  }
1059  }
1060  // Assembling system
1061  LibmeshPetscCall(MatAssemblyBegin(_hc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1062  LibmeshPetscCall(MatAssemblyEnd(_hc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1063  LibmeshPetscCall(MatAssemblyBegin(_hc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1064  LibmeshPetscCall(MatAssemblyEnd(_hc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1065  LibmeshPetscCall(MatAssemblyBegin(_hc_cross_derivative_mat, MAT_FINAL_ASSEMBLY));
1066  LibmeshPetscCall(MatAssemblyEnd(_hc_cross_derivative_mat, MAT_FINAL_ASSEMBLY));
1067  LibmeshPetscCall(MatAssemblyBegin(_hc_axial_heat_conduction_mat, MAT_FINAL_ASSEMBLY));
1068  LibmeshPetscCall(MatAssemblyEnd(_hc_axial_heat_conduction_mat, MAT_FINAL_ASSEMBLY));
1069  LibmeshPetscCall(MatAssemblyBegin(_hc_radial_heat_conduction_mat, MAT_FINAL_ASSEMBLY));
1070  LibmeshPetscCall(MatAssemblyEnd(_hc_radial_heat_conduction_mat, MAT_FINAL_ASSEMBLY));
1071  LibmeshPetscCall(MatAssemblyBegin(_hc_sweep_enthalpy_mat, MAT_FINAL_ASSEMBLY));
1072  LibmeshPetscCall(MatAssemblyEnd(_hc_sweep_enthalpy_mat, MAT_FINAL_ASSEMBLY));
1073  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1074  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1075  // Add all matrices together
1076  LibmeshPetscCall(
1077  MatAXPY(_hc_sys_h_mat, 1.0, _hc_time_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1078  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1079  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1080  LibmeshPetscCall(
1081  MatAXPY(_hc_sys_h_mat, 1.0, _hc_advective_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1082  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1083  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1084  LibmeshPetscCall(
1085  MatAXPY(_hc_sys_h_mat, 1.0, _hc_cross_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1086  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1087  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1088  LibmeshPetscCall(
1089  MatAXPY(_hc_sys_h_mat, 1.0, _hc_axial_heat_conduction_mat, DIFFERENT_NONZERO_PATTERN));
1090  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1091  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1092  LibmeshPetscCall(
1093  MatAXPY(_hc_sys_h_mat, 1.0, _hc_radial_heat_conduction_mat, DIFFERENT_NONZERO_PATTERN));
1094  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1095  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1096  LibmeshPetscCall(
1097  MatAXPY(_hc_sys_h_mat, 1.0, _hc_sweep_enthalpy_mat, DIFFERENT_NONZERO_PATTERN));
1098  LibmeshPetscCall(MatAssemblyBegin(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1099  LibmeshPetscCall(MatAssemblyEnd(_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1100  if (_verbose_subchannel)
1101  _console << "Block: " << iblock << " - Enthalpy conservation matrix assembled" << std::endl;
1102  // RHS
1103  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_time_derivative_rhs));
1104  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_advective_derivative_rhs));
1105  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_cross_derivative_rhs));
1106  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_added_heat_rhs));
1107  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_axial_heat_conduction_rhs));
1108  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_radial_heat_conduction_rhs));
1109  LibmeshPetscCall(VecAXPY(_hc_sys_h_rhs, 1.0, _hc_sweep_enthalpy_rhs));
1110 
1111  // Use system to solve for and populate enthalpy
1112  LibmeshPetscCall(this->solveAndPopulateEnthalpy(
1113  _hc_sys_h_mat, _hc_sys_h_rhs, first_node, last_node, "h_sys_"));
1114  }
1115 }
PetscErrorCode solveAndPopulateEnthalpy(Mat A, Vec rhs, unsigned int first_node, unsigned int last_node, const char *ksp_prefix)
Solve a linear system (A * x = rhs) with a simple PCJACOBI KSP and populate the enthalpy solution int...
const Real & getWireDiameter() const
Return wire diameter.
virtual const Real & getPinDiameter() const
Return undeformed Pin diameter.
std::unique_ptr< SolutionHandle > _T_soln
std::unique_ptr< SolutionHandle > _h_soln
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
static const std::string K
Definition: NS.h:174
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
std::unique_ptr< SolutionHandle > _S_flow_soln
virtual Real computeAddedHeatPin(unsigned int i_ch, unsigned int iz) const override
Pure virtual: daughters provide different implementations.
PetscScalar computeInterpolatedValue(PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
const Real & getDuctToPinGap() const
Return the the gap thickness between the duct and peripheral fuel pins.
std::unique_ptr< SolutionHandle > _rho_soln
static const std::string cp
Definition: NS.h:125
Vec _hc_added_heat_rhs
Enthalpy conservation - source and sink.
std::vector< Real > _z_grid
axial location of nodes
const std::string & name() const
static const std::string pitch
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
Mat _hc_cross_derivative_mat
Enthalpy conservation - cross flux derivative.
Real computeSweepFlowMixingParameter(unsigned int i_gap, unsigned int iz) const
Computes and validates the sweep-flow mixing parameter.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
const MooseEnum _interpolation_scheme
The interpolation method used in constructing the systems.
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
virtual unsigned int getNumOfAxialCells() const
Return the number of axial cells.
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
virtual Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const =0
Return gap width for a given gap index.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
libMesh::DenseMatrix< Real > & _Wij
static const std::string alpha
Definition: NS.h:138
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a sign for the crossflow given a subchannel index and local neighbor index.
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
void mooseError(Args &&... args) const
Mat _hc_advective_derivative_mat
Enthalpy conservation - advective (Eulerian) derivative;.
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
const std::pair< unsigned int, unsigned int > & getSweepFlowChans(unsigned int i_chan) const
const ConsoleStream _console
Mat _hc_time_derivative_mat
Enthalpy Enthalpy conservation - time derivative.
libMesh::DenseMatrix< Real > _WijPrime
const Real & getWireLeadLength() const
Return the wire lead length.
virtual Real computeAddedHeatDuct(unsigned int i_ch, unsigned int iz) const
Non-pure: implemented in the base (or override in a child if needed)
MooseUnits pow(const MooseUnits &, int)
std::unique_ptr< SolutionHandle > _P_soln
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.
Mat _hc_sys_h_mat
System matrices.
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.

◆ computeInterpolatedValue()

PetscScalar SubChannel1PhaseProblem::computeInterpolatedValue ( PetscScalar  topValue,
PetscScalar  botValue,
PetscScalar  Peclet = 0.0 
)
protectedinherited

Definition at line 463 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::computeDP(), QuadSubChannel1PhaseProblem::computeh(), computeh(), SubChannel1PhaseProblem::computeP(), and SubChannel1PhaseProblem::computeWijResidual().

466 {
468  return alpha * botValue + (1.0 - alpha) * topValue;
469 }
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
auto Peclet(const T1 &volume_fraction, const T2 &cp, const T3 &rho, const T4 &vel, const T5 &D_h, const T6 &k)
Compute Peclet number.
Definition: Numerics.h:153
static const std::string alpha
Definition: NS.h:138

◆ computeInterpolationCoefficients()

PetscScalar SubChannel1PhaseProblem::computeInterpolationCoefficients ( PetscScalar  Peclet = 0.0)
protectedinherited

Functions that computes the interpolation scheme given the Peclet number.

Definition at line 443 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::computeDP(), QuadSubChannel1PhaseProblem::computeh(), computeh(), SubChannel1PhaseProblem::computeInterpolatedValue(), SubChannel1PhaseProblem::computeP(), and SubChannel1PhaseProblem::computeWijResidual().

444 {
445  switch (_interpolation_scheme)
446  {
447  case 0: // upwind interpolation
448  return 1.0;
449  case 1: // downwind interpolation
450  return 0.0;
451  case 2: // central_difference interpolation
452  return 0.5;
453  case 3: // exponential interpolation (Peclet limited)
454  return ((Peclet - 1.0) * std::exp(Peclet) + 1) / (Peclet * (std::exp(Peclet) - 1.) + 1e-10);
455  default:
456  mooseError(name(),
457  ": Interpolation scheme should be a string: upwind, downwind, central_difference, "
458  "exponential");
459  }
460 }
const std::string & name() const
auto Peclet(const T1 &volume_fraction, const T2 &cp, const T3 &rho, const T4 &vel, const T5 &D_h, const T6 &k)
Compute Peclet number.
Definition: Numerics.h:153
const MooseEnum _interpolation_scheme
The interpolation method used in constructing the systems.
void mooseError(Args &&... args) const

◆ computeMdot()

void SubChannel1PhaseProblem::computeMdot ( int  iblock)
protectedinherited

Computes mass flow per channel for block iblock.

Definition at line 570 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

571 {
572  const unsigned int last_node = (iblock + 1) * _block_size;
573  const unsigned int first_node = iblock * _block_size + 1;
574  if (!_implicit_bool)
575  {
576  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
577  {
578  auto dz = _z_grid[iz] - _z_grid[iz - 1];
579  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
580  {
581  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
582  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
583  auto volume = dz * (*_S_flow_soln)(node_in);
584  auto time_term = _TR * ((*_rho_soln)(node_out)-_rho_soln->old(node_out)) * volume / _dt;
585  // Wij positive out of i into j;
586  auto mdot_out = (*_mdot_soln)(node_in) - (*_SumWij_soln)(node_out)-time_term;
587  if (mdot_out < 0)
588  {
589  _console << "Wij = : " << _Wij << "\n";
590  mooseError(name(),
591  " : Calculation of negative mass flow mdot_out = : ",
592  mdot_out,
593  " Axial Level= : ",
594  iz,
595  " - Implicit solves are required for recirculating flow.");
596  }
597  _mdot_soln->set(node_out, mdot_out); // kg/sec
598  }
599  }
600  }
601  else
602  {
603  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
604  {
605  auto dz = _z_grid[iz] - _z_grid[iz - 1];
606  auto iz_ind = iz - first_node;
607  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
608  {
609  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
610  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
611  auto volume = dz * (*_S_flow_soln)(node_in);
612 
613  // Adding time derivative to the RHS
614  auto time_term = _TR * ((*_rho_soln)(node_out)-_rho_soln->old(node_out)) * volume / _dt;
615  PetscInt row_vec = i_ch + _n_channels * iz_ind;
616  PetscScalar value_vec = -1.0 * time_term;
617  LibmeshPetscCall(
618  VecSetValues(_mc_axial_convection_rhs, 1, &row_vec, &value_vec, INSERT_VALUES));
619 
620  // Imposing bottom boundary condition or adding of diagonal elements
621  if (iz == first_node)
622  {
623  PetscScalar value_vec = (*_mdot_soln)(node_in);
624  PetscInt row_vec = i_ch + _n_channels * iz_ind;
625  LibmeshPetscCall(
626  VecSetValues(_mc_axial_convection_rhs, 1, &row_vec, &value_vec, ADD_VALUES));
627  }
628  else
629  {
630  PetscInt row = i_ch + _n_channels * iz_ind;
631  PetscInt col = i_ch + _n_channels * (iz_ind - 1);
632  PetscScalar value = -1.0;
633  LibmeshPetscCall(
634  MatSetValues(_mc_axial_convection_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
635  }
636 
637  // Adding diagonal elements
638  PetscInt row = i_ch + _n_channels * iz_ind;
639  PetscInt col = i_ch + _n_channels * iz_ind;
640  PetscScalar value = 1.0;
641  LibmeshPetscCall(
642  MatSetValues(_mc_axial_convection_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
643 
644  // Adding cross flows RHS
645  if (_segregated_bool)
646  {
647  PetscScalar value_vec_2 = -1.0 * (*_SumWij_soln)(node_out);
648  PetscInt row_vec_2 = i_ch + _n_channels * iz_ind;
649  LibmeshPetscCall(
650  VecSetValues(_mc_axial_convection_rhs, 1, &row_vec_2, &value_vec_2, ADD_VALUES));
651  }
652  }
653  }
654  LibmeshPetscCall(MatAssemblyBegin(_mc_axial_convection_mat, MAT_FINAL_ASSEMBLY));
655  LibmeshPetscCall(MatAssemblyEnd(_mc_axial_convection_mat, MAT_FINAL_ASSEMBLY));
656 
657  if (_segregated_bool)
658  {
659  KSP ksploc;
660  PC pc;
661  Vec sol;
662  LibmeshPetscCall(VecDuplicate(_mc_axial_convection_rhs, &sol));
663  LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
664  LibmeshPetscCall(KSPSetOperators(ksploc, _mc_axial_convection_mat, _mc_axial_convection_mat));
665  LibmeshPetscCall(KSPGetPC(ksploc, &pc));
666  LibmeshPetscCall(PCSetType(pc, PCJACOBI));
667  LibmeshPetscCall(KSPSetTolerances(ksploc, _rtol, _atol, _dtol, _maxit));
668  LibmeshPetscCall(KSPSetFromOptions(ksploc));
669  LibmeshPetscCall(KSPSolve(ksploc, _mc_axial_convection_rhs, sol));
670  LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
671  sol, *_mdot_soln, first_node, last_node, _n_channels));
672  LibmeshPetscCall(VecZeroEntries(_mc_axial_convection_rhs));
673  LibmeshPetscCall(KSPDestroy(&ksploc));
674  LibmeshPetscCall(VecDestroy(&sol));
675  }
676  }
677 }
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
const bool _segregated_bool
Segregated solve.
std::unique_ptr< SolutionHandle > _rho_soln
std::vector< Real > _z_grid
axial location of nodes
const std::string & name() const
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
Mat _mc_axial_convection_mat
Mass conservation - axial convection.
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
libMesh::DenseMatrix< Real > & _Wij
std::unique_ptr< SolutionHandle > _SumWij_soln
void mooseError(Args &&... args) const
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
const ConsoleStream _console

◆ computeMixingParameter()

Real SubChannel1PhaseProblem::computeMixingParameter ( unsigned int  i_gap,
unsigned int  iz 
) const
protectedinherited

Computes and validates the turbulent mixing parameter.

Definition at line 1893 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::computeWijPrime().

1894 {
1895  auto beta = _mixing_closure->computeMixingParameter(i_gap, iz);
1896  if (!std::isfinite(beta) || beta < 0.0)
1897  mooseError(name(),
1898  ": Mixing closure returned invalid beta = ",
1899  beta,
1900  " for gap ",
1901  i_gap,
1902  " at axial index ",
1903  iz,
1904  ". Beta must be finite and non-negative.");
1905 
1906  return beta;
1907 }
virtual Real computeMixingParameter(const unsigned int i_gap, const unsigned int iz) const =0
Computes the turbulent mixing coefficient for the local conditions around gap(i_gap) and axial level(...
const SCMMixingClosureBase * _mixing_closure
Turbulent Mixing closure object.
const std::string & name() const
void mooseError(Args &&... args) const

◆ computeMu()

void SubChannel1PhaseProblem::computeMu ( int  iblock)
protectedinherited

Computes Viscosity per channel for block iblock.

Definition at line 1455 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve().

1456 {
1457  const unsigned int last_node = (iblock + 1) * _block_size;
1458  const unsigned int first_node = iblock * _block_size + 1;
1459  if (iblock == 0)
1460  {
1461  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1462  {
1463  auto * node = _subchannel_mesh.getChannelNode(i_ch, 0);
1464  _mu_soln->set(node, _fp->mu_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node)));
1465  }
1466  }
1467  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1468  {
1469  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1470  {
1471  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
1472  _mu_soln->set(node, _fp->mu_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node)));
1473  }
1474  }
1475 }
std::unique_ptr< SolutionHandle > _T_soln
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _P_soln
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.
std::unique_ptr< SolutionHandle > _mu_soln

◆ computeP()

void SubChannel1PhaseProblem::computeP ( int  iblock)
protectedinherited

Computes Pressure per channel for block iblock.

Definition at line 1184 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

1185 {
1186  const unsigned int last_node = (iblock + 1) * _block_size;
1187  const unsigned int first_node = iblock * _block_size + 1;
1188  if (!_implicit_bool)
1189  {
1191  {
1192  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1193  {
1194  // Calculate pressure in the inlet of the cell assuming known outlet
1195  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1196  {
1197  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
1198  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1199  // update Pressure solution
1200  _P_soln->set(node_in, (*_P_soln)(node_out) + _DP(i_ch, iz));
1201  }
1202  }
1203  }
1204  else
1205  {
1206  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1207  {
1208  // Calculate pressure in the inlet of the cell assuming known outlet
1209  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1210  {
1211  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
1212  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1213  // update Pressure solution
1214  // Note: assuming uniform axial discretization in the curren code
1215  // We will need to update this later if we allow non-uniform refinements in the axial
1216  // direction
1217  PetscScalar Pe = 0.5;
1219  if (iz == last_node)
1220  {
1221  _P_soln->set(node_in, (*_P_soln)(node_out) + _DP(i_ch, iz) / 2.0);
1222  }
1223  else
1224  {
1225  _P_soln->set(node_in,
1226  (*_P_soln)(node_out) + (1.0 - alpha) * _DP(i_ch, iz) +
1227  alpha * _DP(i_ch, iz - 1));
1228  }
1229  }
1230  }
1231  }
1232  }
1233  else
1234  {
1236  {
1237  LibmeshPetscCall(VecZeroEntries(_amc_pressure_force_rhs));
1238  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1239  {
1240  auto iz_ind = iz - first_node;
1241  // Calculate pressure in the inlet of the cell assuming known outlet
1242  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1243  {
1244  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
1245  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1246 
1247  // inlet, outlet, and interpolated axial surface area
1248  auto S_in = (*_S_flow_soln)(node_in);
1249  auto S_out = (*_S_flow_soln)(node_out);
1250  auto S_interp = computeInterpolatedValue(S_out, S_in, 0.5);
1251 
1252  // Creating matrix of coefficients
1253  PetscInt row = i_ch + _n_channels * iz_ind;
1254  PetscInt col = i_ch + _n_channels * iz_ind;
1255  PetscScalar value = -1.0 * S_interp;
1256  LibmeshPetscCall(
1257  MatSetValues(_amc_pressure_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1258 
1259  if (iz == last_node)
1260  {
1261  PetscScalar value = -1.0 * (*_P_soln)(node_out)*S_interp;
1262  PetscInt row = i_ch + _n_channels * iz_ind;
1263  LibmeshPetscCall(VecSetValues(_amc_pressure_force_rhs, 1, &row, &value, ADD_VALUES));
1264  }
1265  else
1266  {
1267  PetscInt row = i_ch + _n_channels * iz_ind;
1268  PetscInt col = i_ch + _n_channels * (iz_ind + 1);
1269  PetscScalar value = 1.0 * S_interp;
1270  LibmeshPetscCall(
1271  MatSetValues(_amc_pressure_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1272  }
1273 
1274  if (_segregated_bool)
1275  {
1276  auto dp_out = _DP(i_ch, iz);
1277  PetscScalar value_v = -1.0 * dp_out * S_interp;
1278  PetscInt row_v = i_ch + _n_channels * iz_ind;
1279  LibmeshPetscCall(
1280  VecSetValues(_amc_pressure_force_rhs, 1, &row_v, &value_v, ADD_VALUES));
1281  }
1282  }
1283  }
1284  // Solving pressure problem
1285  LibmeshPetscCall(MatAssemblyBegin(_amc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1286  LibmeshPetscCall(MatAssemblyEnd(_amc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1287  if (_segregated_bool)
1288  {
1289  KSP ksploc;
1290  PC pc;
1291  Vec sol;
1292  LibmeshPetscCall(VecDuplicate(_amc_pressure_force_rhs, &sol));
1293  LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
1294  LibmeshPetscCall(KSPSetOperators(ksploc, _amc_pressure_force_mat, _amc_pressure_force_mat));
1295  LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1296  LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1297  LibmeshPetscCall(KSPSetTolerances(ksploc, _rtol, _atol, _dtol, _maxit));
1298  LibmeshPetscCall(KSPSetFromOptions(ksploc));
1299  LibmeshPetscCall(KSPSolve(ksploc, _amc_pressure_force_rhs, sol));
1300  PetscScalar * xx;
1301  LibmeshPetscCall(VecGetArray(sol, &xx));
1302  // update Pressure solution
1303  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1304  {
1305  auto iz_ind = iz - first_node;
1306  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1307  {
1308  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1309  PetscScalar value = xx[iz_ind * _n_channels + i_ch];
1310  _P_soln->set(node_in, value);
1311  }
1312  }
1313  LibmeshPetscCall(VecZeroEntries(_amc_pressure_force_rhs));
1314  LibmeshPetscCall(KSPDestroy(&ksploc));
1315  LibmeshPetscCall(VecDestroy(&sol));
1316  }
1317  }
1318  else
1319  {
1320  LibmeshPetscCall(VecZeroEntries(_amc_pressure_force_rhs));
1321  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1322  {
1323  auto iz_ind = iz - first_node;
1324  // Calculate pressure in the inlet of the cell assuming known outlet
1325  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1326  {
1327  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
1328  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1329 
1330  // inlet, outlet, and interpolated axial surface area
1331  auto S_in = (*_S_flow_soln)(node_in);
1332  auto S_out = (*_S_flow_soln)(node_out);
1333  auto S_interp = computeInterpolatedValue(S_out, S_in, 0.5);
1334 
1335  // Creating matrix of coefficients
1336  PetscInt row = i_ch + _n_channels * iz_ind;
1337  PetscInt col = i_ch + _n_channels * iz_ind;
1338  PetscScalar value = -1.0 * S_interp;
1339  LibmeshPetscCall(
1340  MatSetValues(_amc_pressure_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1341 
1342  if (iz == last_node)
1343  {
1344  PetscScalar value = -1.0 * (*_P_soln)(node_out)*S_interp;
1345  PetscInt row = i_ch + _n_channels * iz_ind;
1346  LibmeshPetscCall(VecSetValues(_amc_pressure_force_rhs, 1, &row, &value, ADD_VALUES));
1347 
1348  auto dp_out = _DP(i_ch, iz);
1349  PetscScalar value_v = -1.0 * dp_out / 2.0 * S_interp;
1350  PetscInt row_v = i_ch + _n_channels * iz_ind;
1351  LibmeshPetscCall(
1352  VecSetValues(_amc_pressure_force_rhs, 1, &row_v, &value_v, ADD_VALUES));
1353  }
1354  else
1355  {
1356  PetscInt row = i_ch + _n_channels * iz_ind;
1357  PetscInt col = i_ch + _n_channels * (iz_ind + 1);
1358  PetscScalar value = 1.0 * S_interp;
1359  LibmeshPetscCall(
1360  MatSetValues(_amc_pressure_force_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
1361 
1362  if (_segregated_bool)
1363  {
1364  auto dp_in = _DP(i_ch, iz - 1);
1365  auto dp_out = _DP(i_ch, iz);
1366  auto dp_interp = computeInterpolatedValue(dp_out, dp_in, 0.5);
1367  PetscScalar value_v = -1.0 * dp_interp * S_interp;
1368  PetscInt row_v = i_ch + _n_channels * iz_ind;
1369  LibmeshPetscCall(
1370  VecSetValues(_amc_pressure_force_rhs, 1, &row_v, &value_v, ADD_VALUES));
1371  }
1372  }
1373  }
1374  }
1375  // Solving pressure problem
1376  LibmeshPetscCall(MatAssemblyBegin(_amc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1377  LibmeshPetscCall(MatAssemblyEnd(_amc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1378  if (_verbose_subchannel)
1379  _console << "Block: " << iblock << " - Axial momentum pressure force matrix assembled"
1380  << std::endl;
1381 
1382  if (_segregated_bool)
1383  {
1384  KSP ksploc;
1385  PC pc;
1386  Vec sol;
1387  LibmeshPetscCall(VecDuplicate(_amc_pressure_force_rhs, &sol));
1388  LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
1389  LibmeshPetscCall(KSPSetOperators(ksploc, _amc_pressure_force_mat, _amc_pressure_force_mat));
1390  LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1391  LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1392  LibmeshPetscCall(KSPSetTolerances(ksploc, _rtol, _atol, _dtol, _maxit));
1393  LibmeshPetscCall(KSPSetFromOptions(ksploc));
1394  LibmeshPetscCall(KSPSolve(ksploc, _amc_pressure_force_rhs, sol));
1395  PetscScalar * xx;
1396  LibmeshPetscCall(VecGetArray(sol, &xx));
1397  // update Pressure solution
1398  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
1399  {
1400  auto iz_ind = iz - first_node;
1401  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1402  {
1403  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1404  PetscScalar value = xx[iz_ind * _n_channels + i_ch];
1405  _P_soln->set(node_in, value);
1406  }
1407  }
1408  LibmeshPetscCall(VecZeroEntries(_amc_pressure_force_rhs));
1409  LibmeshPetscCall(KSPDestroy(&ksploc));
1410  LibmeshPetscCall(VecDestroy(&sol));
1411  }
1412  }
1413  }
1414 }
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
libMesh::DenseMatrix< Real > _DP
PetscScalar computeInterpolatedValue(PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
const bool _segregated_bool
Segregated solve.
const bool _staggered_pressure_bool
Flag to define the usage of staggered or collocated pressure.
Mat _amc_pressure_force_mat
Axial momentum conservation - pressure force.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
static const std::string alpha
Definition: NS.h:138
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
const ConsoleStream _console
std::unique_ptr< SolutionHandle > _P_soln

◆ computeRho()

void SubChannel1PhaseProblem::computeRho ( int  iblock)
protectedinherited

Computes Density per channel for block iblock.

Definition at line 1432 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve().

1433 {
1434  const unsigned int last_node = (iblock + 1) * _block_size;
1435  const unsigned int first_node = iblock * _block_size + 1;
1436  if (iblock == 0)
1437  {
1438  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1439  {
1440  auto * node = _subchannel_mesh.getChannelNode(i_ch, 0);
1441  _rho_soln->set(node, _fp->rho_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node)));
1442  }
1443  }
1444  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1445  {
1446  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1447  {
1448  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
1449  _rho_soln->set(node, _fp->rho_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node)));
1450  }
1451  }
1452 }
std::unique_ptr< SolutionHandle > _T_soln
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.
std::unique_ptr< SolutionHandle > _rho_soln
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _P_soln
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.

◆ computeSumWij()

void SubChannel1PhaseProblem::computeSumWij ( int  iblock)
protectedinherited

Computes net diversion crossflow per channel for block iblock.

Definition at line 505 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

506 {
507  const unsigned int last_node = (iblock + 1) * _block_size;
508  const unsigned int first_node = iblock * _block_size + 1;
509  // Add to solution vector if explicit
510  if (!_implicit_bool)
511  {
512  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
513  {
514  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
515  {
516  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
517  Real sumWij = 0.0;
518  // Calculate sum of crossflow into channel i from channels j around i
519  unsigned int counter = 0;
520  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
521  {
522  sumWij += _subchannel_mesh.getCrossflowSign(i_ch, counter) * _Wij(i_gap, iz);
523  counter++;
524  }
525  // The net crossflow coming out of cell i [kg/sec]
526  _SumWij_soln->set(node_out, sumWij);
527  }
528  }
529  }
530  // Add to matrix if implicit
531  else
532  {
533  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
534  {
535  unsigned int iz_ind = iz - first_node;
536  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
537  {
538  // Calculate sum of crossflow into channel i from channels j around i
539  unsigned int counter = 0;
540  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
541  {
542  PetscInt row = i_ch + _n_channels * iz_ind;
543  PetscInt col = i_gap + _n_gaps * iz_ind;
544  PetscScalar value = _subchannel_mesh.getCrossflowSign(i_ch, counter);
545  LibmeshPetscCall(MatSetValues(_mc_sumWij_mat, 1, &row, 1, &col, &value, INSERT_VALUES));
546  counter++;
547  }
548  }
549  }
550  LibmeshPetscCall(MatAssemblyBegin(_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
551  LibmeshPetscCall(MatAssemblyEnd(_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
552  if (_segregated_bool)
553  {
554  Vec loc_prod;
555  Vec loc_Wij;
556  LibmeshPetscCall(VecDuplicate(_amc_sys_mdot_rhs, &loc_prod));
557  LibmeshPetscCall(VecDuplicate(_Wij_vec, &loc_Wij));
559  loc_Wij, _Wij, first_node, last_node, _n_gaps));
560  LibmeshPetscCall(MatMult(_mc_sumWij_mat, loc_Wij, loc_prod));
561  LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
562  loc_prod, *_SumWij_soln, first_node, last_node, _n_channels));
563  LibmeshPetscCall(VecDestroy(&loc_prod));
564  LibmeshPetscCall(VecDestroy(&loc_Wij));
565  }
566  }
567 }
const bool _segregated_bool
Segregated solve.
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
Mat _mc_sumWij_mat
Matrices and vectors to be used in implicit assembly Mass conservation Mass conservation - sum of cro...
PetscErrorCode populateVectorFromDense(Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
libMesh::DenseMatrix< Real > & _Wij
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a sign for the crossflow given a subchannel index and local neighbor index.
std::unique_ptr< SolutionHandle > _SumWij_soln
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.

◆ computeSweepFlowMixingParameter()

Real SubChannel1PhaseProblem::computeSweepFlowMixingParameter ( unsigned int  i_gap,
unsigned int  iz 
) const
protectedinherited

Computes and validates the sweep-flow mixing parameter.

Definition at line 1910 of file SubChannel1PhaseProblem.C.

Referenced by computeh().

1911 {
1912  auto beta = _mixing_closure->computeSweepFlowMixingParameter(i_gap, iz);
1913  if (!std::isfinite(beta) || beta < 0.0)
1914  mooseError(name(),
1915  ": Mixing closure returned invalid sweep-flow coefficient = ",
1916  beta,
1917  " for gap ",
1918  i_gap,
1919  " at axial index ",
1920  iz,
1921  ". sweep-flow coefficient must be finite and non-negative.");
1922 
1923  return beta;
1924 }
const SCMMixingClosureBase * _mixing_closure
Turbulent Mixing closure object.
const std::string & name() const
virtual Real computeSweepFlowMixingParameter(const unsigned int i_gap, const unsigned int iz) const
Computes the wire-wrap sweep-flow coefficient for peripheral gaps.
void mooseError(Args &&... args) const

◆ computeT()

void SubChannel1PhaseProblem::computeT ( int  iblock)
protectedinherited

Computes Temperature per channel for block iblock.

Definition at line 1417 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve().

1418 {
1419  const unsigned int last_node = (iblock + 1) * _block_size;
1420  const unsigned int first_node = iblock * _block_size + 1;
1421  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1422  {
1423  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
1424  {
1425  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
1426  _T_soln->set(node, _fp->T_from_p_h((*_P_soln)(node) + _P_out, (*_h_soln)(node)));
1427  }
1428  }
1429 }
std::unique_ptr< SolutionHandle > _T_soln
std::unique_ptr< SolutionHandle > _h_soln
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _P_soln
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.

◆ computeWijFromSolve()

void SubChannel1PhaseProblem::computeWijFromSolve ( int  iblock)
protectedinherited

Computes diversion crossflow per gap for block iblock.

Definition at line 472 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve().

473 {
474  const unsigned int last_node = (iblock + 1) * _block_size;
475  const unsigned int first_node = iblock * _block_size + 1;
476  // Initial guess, port crossflow of block (iblock) into a vector that will act as my initial guess
477  libMesh::DenseVector<Real> solution_seed(_n_gaps * _block_size, 0.0);
478  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
479  {
480  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
481  {
482  int i = _n_gaps * (iz - first_node) + i_gap; // column wise transfer
483  solution_seed(i) = _Wij(i_gap, iz);
484  }
485  }
486 
487  // Solving the combined lateral momentum equation for Wij using a PETSc solver and update vector
488  // root
490  LibmeshPetscCall(petscSnesSolver(iblock, solution_seed, root));
491 
492  // Assign the solution to the cross-flow matrix
493  int i = 0;
494  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
495  {
496  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
497  {
498  _Wij(i_gap, iz) = root(i);
499  i++;
500  }
501  }
502 }
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent&#39;s method.
Definition: BrentsMethod.C:66
libMesh::DenseMatrix< Real > & _Wij
PetscErrorCode petscSnesSolver(int iblock, const libMesh::DenseVector< Real > &solution, libMesh::DenseVector< Real > &root)
Computes solution of nonlinear equation using snes and provided a residual in a formFunction.

◆ computeWijPrime()

void SubChannel1PhaseProblem::computeWijPrime ( int  iblock)
protectedinherited

Computes turbulent crossflow per gap for block iblock.

Update turbulent crossflow

Definition at line 1797 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve(), SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

1798 {
1799  const unsigned int last_node = (iblock + 1) * _block_size;
1800  const unsigned int first_node = iblock * _block_size + 1;
1801  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1802  {
1803  auto dz = _z_grid[iz] - _z_grid[iz - 1];
1804  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1805  {
1806  auto chans = _subchannel_mesh.getGapChannels(i_gap);
1807  unsigned int i_ch = chans.first;
1808  unsigned int j_ch = chans.second;
1809  auto * node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1810  auto * node_out_i = _subchannel_mesh.getChannelNode(i_ch, iz);
1811  auto * node_in_j = _subchannel_mesh.getChannelNode(j_ch, iz - 1);
1812  auto * node_out_j = _subchannel_mesh.getChannelNode(j_ch, iz);
1813  auto Si_in = (*_S_flow_soln)(node_in_i);
1814  auto Sj_in = (*_S_flow_soln)(node_in_j);
1815  auto Si_out = (*_S_flow_soln)(node_out_i);
1816  auto Sj_out = (*_S_flow_soln)(node_out_j);
1817  auto gap = _subchannel_mesh.getGapWidth(iz, i_gap);
1818  auto Sij = dz * gap;
1819  auto avg_massflux =
1820  0.5 * (((*_mdot_soln)(node_in_i) + (*_mdot_soln)(node_in_j)) / (Si_in + Sj_in) +
1821  ((*_mdot_soln)(node_out_i) + (*_mdot_soln)(node_out_j)) / (Si_out + Sj_out));
1822  auto beta = computeMixingParameter(i_gap, iz);
1823 
1824  if (!_implicit_bool)
1825  {
1826  _WijPrime(i_gap, iz) = beta * avg_massflux * Sij;
1827  }
1828  else
1829  {
1830  auto iz_ind = iz - first_node;
1831  PetscScalar base_value = beta * 0.5 * Sij;
1832 
1833  // Bottom values
1834  if (iz == first_node)
1835  {
1836  PetscScalar value_tl = -1.0 * base_value / (Si_in + Sj_in) *
1837  ((*_mdot_soln)(node_in_i) + (*_mdot_soln)(node_in_j));
1838  PetscInt row = i_gap + _n_gaps * iz_ind;
1839  LibmeshPetscCall(
1840  VecSetValues(_amc_turbulent_cross_flows_rhs, 1, &row, &value_tl, INSERT_VALUES));
1841  }
1842  else
1843  {
1844  PetscScalar value_tl = base_value / (Si_in + Sj_in);
1845  PetscInt row = i_gap + _n_gaps * iz_ind;
1846 
1847  PetscInt col_ich = i_ch + _n_channels * (iz_ind - 1);
1848  LibmeshPetscCall(MatSetValues(
1849  _amc_turbulent_cross_flows_mat, 1, &row, 1, &col_ich, &value_tl, INSERT_VALUES));
1850 
1851  PetscInt col_jch = j_ch + _n_channels * (iz_ind - 1);
1852  LibmeshPetscCall(MatSetValues(
1853  _amc_turbulent_cross_flows_mat, 1, &row, 1, &col_jch, &value_tl, INSERT_VALUES));
1854  }
1855 
1856  // Top values
1857  PetscScalar value_bl = base_value / (Si_out + Sj_out);
1858  PetscInt row = i_gap + _n_gaps * iz_ind;
1859 
1860  PetscInt col_ich = i_ch + _n_channels * iz_ind;
1861  LibmeshPetscCall(MatSetValues(
1862  _amc_turbulent_cross_flows_mat, 1, &row, 1, &col_ich, &value_bl, INSERT_VALUES));
1863 
1864  PetscInt col_jch = j_ch + _n_channels * iz_ind;
1865  LibmeshPetscCall(MatSetValues(
1866  _amc_turbulent_cross_flows_mat, 1, &row, 1, &col_jch, &value_bl, INSERT_VALUES));
1867  }
1868  }
1869  }
1870 
1871  if (_implicit_bool)
1872  {
1873  LibmeshPetscCall(MatAssemblyBegin(_amc_turbulent_cross_flows_mat, MAT_FINAL_ASSEMBLY));
1874  LibmeshPetscCall(MatAssemblyEnd(_amc_turbulent_cross_flows_mat, MAT_FINAL_ASSEMBLY));
1875 
1877  Vec loc_prod;
1878  Vec loc_Wij;
1879  LibmeshPetscCall(VecDuplicate(_amc_sys_mdot_rhs, &loc_prod));
1880  LibmeshPetscCall(VecDuplicate(_Wij_vec, &loc_Wij));
1881  LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1882  loc_prod, *_mdot_soln, first_node, last_node, _n_channels));
1883  LibmeshPetscCall(MatMult(_amc_turbulent_cross_flows_mat, loc_prod, loc_Wij));
1884  LibmeshPetscCall(VecAXPY(loc_Wij, -1.0, _amc_turbulent_cross_flows_rhs));
1886  loc_Wij, _WijPrime, first_node, last_node, _n_gaps));
1887  LibmeshPetscCall(VecDestroy(&loc_prod));
1888  LibmeshPetscCall(VecDestroy(&loc_Wij));
1889  }
1890 }
Real computeMixingParameter(unsigned int i_gap, unsigned int iz) const
Computes and validates the turbulent mixing parameter.
Mat _amc_turbulent_cross_flows_mat
Mass conservation - density time derivative No implicit matrix.
std::vector< Real > _z_grid
axial location of nodes
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
PetscErrorCode populateDenseFromVector(const Vec &x, T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
virtual Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const =0
Return gap width for a given gap index.
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
libMesh::DenseMatrix< Real > _WijPrime
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.

◆ computeWijResidual()

void SubChannel1PhaseProblem::computeWijResidual ( int  iblock)
protectedinherited

Computes Residual Matrix based on the lateral momentum conservation equation for block iblock.

Assembling system

Definition at line 1478 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::residualFunction().

1479 {
1480  const unsigned int last_node = (iblock + 1) * _block_size;
1481  const unsigned int first_node = iblock * _block_size + 1;
1482  // Cross flow residual
1483  if (!_implicit_bool)
1484  {
1485  const Real & pitch = _subchannel_mesh.getPitch();
1486  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1487  {
1488  auto dz = _z_grid[iz] - _z_grid[iz - 1];
1489  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1490  {
1491  auto chans = _subchannel_mesh.getGapChannels(i_gap);
1492  unsigned int i_ch = chans.first;
1493  unsigned int j_ch = chans.second;
1494  auto * node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1495  auto * node_out_i = _subchannel_mesh.getChannelNode(i_ch, iz);
1496  auto * node_in_j = _subchannel_mesh.getChannelNode(j_ch, iz - 1);
1497  auto * node_out_j = _subchannel_mesh.getChannelNode(j_ch, iz);
1498  auto rho_i = (*_rho_soln)(node_in_i);
1499  auto rho_j = (*_rho_soln)(node_in_j);
1500  auto Si = (*_S_flow_soln)(node_in_i);
1501  auto Sj = (*_S_flow_soln)(node_in_j);
1502  auto Sij = dz * _subchannel_mesh.getGapWidth(iz, i_gap);
1503  auto Lij = pitch;
1504  // total local form loss in the ij direction
1505  auto friction_term = _kij * _Wij(i_gap, iz) * std::abs(_Wij(i_gap, iz));
1506  auto DPij = (*_P_soln)(node_in_i) - (*_P_soln)(node_in_j);
1507  // Figure out donor cell density
1508  auto rho_star = 0.0;
1509  if (_Wij(i_gap, iz) > 0.0)
1510  rho_star = rho_i;
1511  else if (_Wij(i_gap, iz) < 0.0)
1512  rho_star = rho_j;
1513  else
1514  rho_star = (rho_i + rho_j) / 2.0;
1515  auto mass_term_out =
1516  (*_mdot_soln)(node_out_i) / (*_S_flow_soln)(node_out_i) / (*_rho_soln)(node_out_i) +
1517  (*_mdot_soln)(node_out_j) / (*_S_flow_soln)(node_out_j) / (*_rho_soln)(node_out_j);
1518  auto mass_term_in =
1519  (*_mdot_soln)(node_in_i) / Si / rho_i + (*_mdot_soln)(node_in_j) / Sj / rho_j;
1520  auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out * _Wij(i_gap, iz);
1521  auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in * _Wij(i_gap, iz - 1);
1522  auto inertia_term = term_out - term_in;
1523  auto pressure_term = 2 * Utility::pow<2>(Sij) * DPij * rho_star;
1524  auto time_term =
1525  _TR * 2.0 * (_Wij(i_gap, iz) - _Wij_old(i_gap, iz)) * Lij * Sij * rho_star / _dt;
1526 
1527  _Wij_residual_matrix(i_gap, iz - 1 - iblock * _block_size) =
1528  time_term + friction_term + inertia_term - pressure_term;
1529  }
1530  }
1531  }
1532  else
1533  {
1534  // Initializing to zero the elements of the lateral momentum assembly
1535  LibmeshPetscCall(MatZeroEntries(_cmc_time_derivative_mat));
1536  LibmeshPetscCall(MatZeroEntries(_cmc_advective_derivative_mat));
1537  LibmeshPetscCall(MatZeroEntries(_cmc_friction_force_mat));
1538  LibmeshPetscCall(MatZeroEntries(_cmc_pressure_force_mat));
1539  LibmeshPetscCall(VecZeroEntries(_cmc_time_derivative_rhs));
1540  LibmeshPetscCall(VecZeroEntries(_cmc_advective_derivative_rhs));
1541  LibmeshPetscCall(VecZeroEntries(_cmc_friction_force_rhs));
1542  LibmeshPetscCall(VecZeroEntries(_cmc_pressure_force_rhs));
1543  LibmeshPetscCall(MatZeroEntries(_cmc_sys_Wij_mat));
1544  LibmeshPetscCall(VecZeroEntries(_cmc_sys_Wij_rhs));
1545  const Real & pitch = _subchannel_mesh.getPitch();
1546  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1547  {
1548  auto dz = _z_grid[iz] - _z_grid[iz - 1];
1549  auto iz_ind = iz - first_node;
1550  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1551  {
1552  auto chans = _subchannel_mesh.getGapChannels(i_gap);
1553  unsigned int i_ch = chans.first;
1554  unsigned int j_ch = chans.second;
1555  auto * node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
1556  auto * node_out_i = _subchannel_mesh.getChannelNode(i_ch, iz);
1557  auto * node_in_j = _subchannel_mesh.getChannelNode(j_ch, iz - 1);
1558  auto * node_out_j = _subchannel_mesh.getChannelNode(j_ch, iz);
1559 
1560  // inlet, outlet, and interpolated densities
1561  auto rho_i_in = (*_rho_soln)(node_in_i);
1562  auto rho_i_out = (*_rho_soln)(node_out_i);
1563  auto rho_i_interp = computeInterpolatedValue(rho_i_out, rho_i_in, 0.5);
1564  auto rho_j_in = (*_rho_soln)(node_in_j);
1565  auto rho_j_out = (*_rho_soln)(node_out_j);
1566  auto rho_j_interp = computeInterpolatedValue(rho_j_out, rho_j_in, 0.5);
1567 
1568  // inlet, outlet, and interpolated areas
1569  auto S_i_in = (*_S_flow_soln)(node_in_i);
1570  auto S_i_out = (*_S_flow_soln)(node_out_i);
1571  auto S_j_in = (*_S_flow_soln)(node_in_j);
1572  auto S_j_out = (*_S_flow_soln)(node_out_j);
1573 
1574  // Cross-sectional gap area
1575  auto Sij = dz * _subchannel_mesh.getGapWidth(iz, i_gap);
1576  auto Lij = pitch;
1577 
1578  // Figure out donor cell density
1579  auto rho_star = 0.0;
1580  if (_Wij(i_gap, iz) > 0.0)
1581  rho_star = rho_i_interp;
1582  else if (_Wij(i_gap, iz) < 0.0)
1583  rho_star = rho_j_interp;
1584  else
1585  rho_star = (rho_i_interp + rho_j_interp) / 2.0;
1586 
1587  // Assembling time derivative
1588  PetscScalar time_factor = _TR * Lij * Sij * rho_star / _dt;
1589  PetscInt row_td = i_gap + _n_gaps * iz_ind;
1590  PetscInt col_td = i_gap + _n_gaps * iz_ind;
1591  PetscScalar value_td = time_factor;
1592  LibmeshPetscCall(MatSetValues(
1593  _cmc_time_derivative_mat, 1, &row_td, 1, &col_td, &value_td, INSERT_VALUES));
1594  PetscScalar value_td_rhs = time_factor * _Wij_old(i_gap, iz);
1595  LibmeshPetscCall(
1596  VecSetValues(_cmc_time_derivative_rhs, 1, &row_td, &value_td_rhs, INSERT_VALUES));
1597 
1598  // Assembling inertial term
1599  PetscScalar Pe = 0.5;
1601  auto mass_term_out = (*_mdot_soln)(node_out_i) / S_i_out / rho_i_out +
1602  (*_mdot_soln)(node_out_j) / S_j_out / rho_j_out;
1603  auto mass_term_in = (*_mdot_soln)(node_in_i) / S_i_in / rho_i_in +
1604  (*_mdot_soln)(node_in_j) / S_j_in / rho_j_in;
1605  auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out / 2.0;
1606  auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in / 2.0;
1607  if (iz == first_node)
1608  {
1609  PetscInt row_ad = i_gap + _n_gaps * iz_ind;
1610  PetscScalar value_ad = term_in * alpha * _Wij(i_gap, iz - 1);
1611  LibmeshPetscCall(
1612  VecSetValues(_cmc_advective_derivative_rhs, 1, &row_ad, &value_ad, ADD_VALUES));
1613 
1614  PetscInt col_ad = i_gap + _n_gaps * iz_ind;
1615  value_ad = -1.0 * term_in * (1.0 - alpha) + term_out * alpha;
1616  LibmeshPetscCall(MatSetValues(
1617  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1618 
1619  col_ad = i_gap + _n_gaps * (iz_ind + 1);
1620  value_ad = term_out * (1.0 - alpha);
1621  LibmeshPetscCall(MatSetValues(
1622  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1623  }
1624  else if (iz == last_node)
1625  {
1626  PetscInt row_ad = i_gap + _n_gaps * iz_ind;
1627  PetscInt col_ad = i_gap + _n_gaps * (iz_ind - 1);
1628  PetscScalar value_ad = -1.0 * term_in * alpha;
1629  LibmeshPetscCall(MatSetValues(
1630  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1631 
1632  col_ad = i_gap + _n_gaps * iz_ind;
1633  value_ad = -1.0 * term_in * (1.0 - alpha) + term_out * alpha;
1634  LibmeshPetscCall(MatSetValues(
1635  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1636 
1637  value_ad = -1.0 * term_out * (1.0 - alpha) * _Wij(i_gap, iz);
1638  LibmeshPetscCall(
1639  VecSetValues(_cmc_advective_derivative_rhs, 1, &row_ad, &value_ad, ADD_VALUES));
1640  }
1641  else
1642  {
1643  PetscInt row_ad = i_gap + _n_gaps * iz_ind;
1644  PetscInt col_ad = i_gap + _n_gaps * (iz_ind - 1);
1645  PetscScalar value_ad = -1.0 * term_in * alpha;
1646  LibmeshPetscCall(MatSetValues(
1647  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1648 
1649  col_ad = i_gap + _n_gaps * iz_ind;
1650  value_ad = -1.0 * term_in * (1.0 - alpha) + term_out * alpha;
1651  LibmeshPetscCall(MatSetValues(
1652  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1653 
1654  col_ad = i_gap + _n_gaps * (iz_ind + 1);
1655  value_ad = term_out * (1.0 - alpha);
1656  LibmeshPetscCall(MatSetValues(
1657  _cmc_advective_derivative_mat, 1, &row_ad, 1, &col_ad, &value_ad, INSERT_VALUES));
1658  }
1659  // Assembling friction force
1660  PetscInt row_ff = i_gap + _n_gaps * iz_ind;
1661  PetscInt col_ff = i_gap + _n_gaps * iz_ind;
1662  PetscScalar value_ff = _kij * std::abs(_Wij(i_gap, iz)) / 2.0;
1663  LibmeshPetscCall(MatSetValues(
1664  _cmc_friction_force_mat, 1, &row_ff, 1, &col_ff, &value_ff, INSERT_VALUES));
1665 
1666  // Assembling pressure force
1668 
1670  {
1671  PetscScalar pressure_factor = Utility::pow<2>(Sij) * rho_star;
1672  PetscInt row_pf = i_gap + _n_gaps * iz_ind;
1673  PetscInt col_pf = i_ch + _n_channels * iz_ind;
1674  PetscScalar value_pf = -1.0 * alpha * pressure_factor;
1675  LibmeshPetscCall(
1676  MatSetValues(_cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1677  col_pf = j_ch + _n_channels * iz_ind;
1678  value_pf = alpha * pressure_factor;
1679  LibmeshPetscCall(
1680  MatSetValues(_cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1681 
1682  if (iz == last_node)
1683  {
1684  PetscInt row_pf = i_gap + _n_gaps * iz_ind;
1685  PetscScalar value_pf = (1.0 - alpha) * pressure_factor * (*_P_soln)(node_out_i);
1686  LibmeshPetscCall(
1687  VecSetValues(_cmc_pressure_force_rhs, 1, &row_pf, &value_pf, ADD_VALUES));
1688  value_pf = -1.0 * (1.0 - alpha) * pressure_factor * (*_P_soln)(node_out_j);
1689  LibmeshPetscCall(
1690  VecSetValues(_cmc_pressure_force_rhs, 1, &row_pf, &value_pf, ADD_VALUES));
1691  }
1692  else
1693  {
1694  row_pf = i_gap + _n_gaps * iz_ind;
1695  col_pf = i_ch + _n_channels * (iz_ind + 1);
1696  value_pf = -1.0 * (1.0 - alpha) * pressure_factor;
1697  LibmeshPetscCall(MatSetValues(
1698  _cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1699  col_pf = j_ch + _n_channels * (iz_ind + 1);
1700  value_pf = (1.0 - alpha) * pressure_factor;
1701  LibmeshPetscCall(MatSetValues(
1702  _cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1703  }
1704  }
1705  else
1706  {
1707  PetscScalar pressure_factor = Utility::pow<2>(Sij) * rho_star;
1708  PetscInt row_pf = i_gap + _n_gaps * iz_ind;
1709  PetscInt col_pf = i_ch + _n_channels * iz_ind;
1710  PetscScalar value_pf = -1.0 * pressure_factor;
1711  LibmeshPetscCall(
1712  MatSetValues(_cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1713  col_pf = j_ch + _n_channels * iz_ind;
1714  value_pf = pressure_factor;
1715  LibmeshPetscCall(
1716  MatSetValues(_cmc_pressure_force_mat, 1, &row_pf, 1, &col_pf, &value_pf, ADD_VALUES));
1717  }
1718  }
1719  }
1721  LibmeshPetscCall(MatZeroEntries(_cmc_sys_Wij_mat));
1722  LibmeshPetscCall(VecZeroEntries(_cmc_sys_Wij_rhs));
1723  LibmeshPetscCall(MatAssemblyBegin(_cmc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1724  LibmeshPetscCall(MatAssemblyEnd(_cmc_time_derivative_mat, MAT_FINAL_ASSEMBLY));
1725  LibmeshPetscCall(MatAssemblyBegin(_cmc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1726  LibmeshPetscCall(MatAssemblyEnd(_cmc_advective_derivative_mat, MAT_FINAL_ASSEMBLY));
1727  LibmeshPetscCall(MatAssemblyBegin(_cmc_friction_force_mat, MAT_FINAL_ASSEMBLY));
1728  LibmeshPetscCall(MatAssemblyEnd(_cmc_friction_force_mat, MAT_FINAL_ASSEMBLY));
1729  LibmeshPetscCall(MatAssemblyBegin(_cmc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1730  LibmeshPetscCall(MatAssemblyEnd(_cmc_pressure_force_mat, MAT_FINAL_ASSEMBLY));
1731  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1732  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1733  // Matrix
1734 #if !PETSC_VERSION_LESS_THAN(3, 15, 0)
1735  LibmeshPetscCall(
1736  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_time_derivative_mat, UNKNOWN_NONZERO_PATTERN));
1737  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1738  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1739  LibmeshPetscCall(
1740  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_advective_derivative_mat, UNKNOWN_NONZERO_PATTERN));
1741  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1742  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1743  LibmeshPetscCall(
1744  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_friction_force_mat, UNKNOWN_NONZERO_PATTERN));
1745 #else
1746  LibmeshPetscCall(
1747  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_time_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1748  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1749  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1750  LibmeshPetscCall(
1751  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_advective_derivative_mat, DIFFERENT_NONZERO_PATTERN));
1752  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1753  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1754  LibmeshPetscCall(
1755  MatAXPY(_cmc_sys_Wij_mat, 1.0, _cmc_friction_force_mat, DIFFERENT_NONZERO_PATTERN));
1756 #endif
1757  LibmeshPetscCall(MatAssemblyBegin(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1758  LibmeshPetscCall(MatAssemblyEnd(_cmc_sys_Wij_mat, MAT_FINAL_ASSEMBLY));
1759  // RHS
1760  LibmeshPetscCall(VecAXPY(_cmc_sys_Wij_rhs, 1.0, _cmc_time_derivative_rhs));
1761  LibmeshPetscCall(VecAXPY(_cmc_sys_Wij_rhs, 1.0, _cmc_advective_derivative_rhs));
1762  LibmeshPetscCall(VecAXPY(_cmc_sys_Wij_rhs, 1.0, _cmc_friction_force_rhs));
1763 
1764  if (_segregated_bool)
1765  {
1766  // Assembly the matrix system
1767  Vec sol_holder_P;
1768  LibmeshPetscCall(createPetscVector(sol_holder_P, _block_size * _n_gaps));
1769  Vec sol_holder_W;
1770  LibmeshPetscCall(createPetscVector(sol_holder_W, _block_size * _n_gaps));
1771  LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1772  _prodp, *_P_soln, first_node - 1, last_node - 1, _n_channels));
1774  _Wij_vec, _Wij, first_node, last_node, _n_gaps));
1775  LibmeshPetscCall(MatMult(_cmc_sys_Wij_mat, _Wij_vec, sol_holder_W));
1776  LibmeshPetscCall(VecAXPY(sol_holder_W, -1.0, _cmc_sys_Wij_rhs));
1777  LibmeshPetscCall(MatMult(_cmc_pressure_force_mat, _prodp, sol_holder_P));
1778  LibmeshPetscCall(VecAXPY(sol_holder_P, -1.0, _cmc_pressure_force_rhs));
1779  LibmeshPetscCall(VecAXPY(sol_holder_W, 1.0, sol_holder_P));
1780  PetscScalar * xx;
1781  LibmeshPetscCall(VecGetArray(sol_holder_W, &xx));
1782  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1783  {
1784  auto iz_ind = iz - first_node;
1785  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1786  {
1787  _Wij_residual_matrix(i_gap, iz - 1 - iblock * _block_size) = xx[iz_ind * _n_gaps + i_gap];
1788  }
1789  }
1790  LibmeshPetscCall(VecDestroy(&sol_holder_P));
1791  LibmeshPetscCall(VecDestroy(&sol_holder_W));
1792  }
1793  }
1794 }
Mat _cmc_friction_force_mat
Cross momentum conservation - friction force.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
libMesh::DenseMatrix< Real > _Wij_old
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
std::unique_ptr< SolutionHandle > _S_flow_soln
PetscErrorCode createPetscVector(Vec &v, PetscInt n)
Petsc Functions.
PetscScalar computeInterpolatedValue(PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
const bool _segregated_bool
Segregated solve.
Mat _cmc_sys_Wij_mat
Lateral momentum system matrix.
const bool _staggered_pressure_bool
Flag to define the usage of staggered or collocated pressure.
PetscErrorCode populateVectorFromDense(Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
std::unique_ptr< SolutionHandle > _rho_soln
std::vector< Real > _z_grid
axial location of nodes
static const std::string pitch
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
libMesh::DenseMatrix< Real > _Wij_residual_matrix
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
virtual Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const =0
Return gap width for a given gap index.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
libMesh::DenseMatrix< Real > & _Wij
static const std::string alpha
Definition: NS.h:138
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
Mat _cmc_time_derivative_mat
Cross momentum Cross momentum conservation - time derivative.
Mat _cmc_pressure_force_mat
Cross momentum conservation - pressure force.
std::unique_ptr< SolutionHandle > _P_soln
Mat _cmc_advective_derivative_mat
Cross momentum conservation - advective (Eulerian) derivative.
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.

◆ createPetscMatrix()

PetscErrorCode SubChannel1PhaseProblem::createPetscMatrix ( Mat &  M,
PetscInt  n,
PetscInt  m 
)
inlineprotectedinherited

Definition at line 300 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::SubChannel1PhaseProblem(), and TriSubChannel1PhaseProblem().

301  {
303  LibmeshPetscCall(MatCreate(PETSC_COMM_SELF, &M));
304  LibmeshPetscCall(MatSetSizes(M, PETSC_DECIDE, PETSC_DECIDE, n, m));
305  LibmeshPetscCall(MatSetFromOptions(M));
306  LibmeshPetscCall(MatSetUp(M));
307  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
308  }
const double M
PetscFunctionBegin
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ createPetscVector()

PetscErrorCode SubChannel1PhaseProblem::createPetscVector ( Vec &  v,
PetscInt  n 
)
inlineprotectedinherited

Petsc Functions.

Definition at line 289 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeWijResidual(), SubChannel1PhaseProblem::implicitPetscSolve(), SubChannel1PhaseProblem::SubChannel1PhaseProblem(), and TriSubChannel1PhaseProblem().

290  {
292  LibmeshPetscCall(VecCreate(PETSC_COMM_SELF, &v));
293  LibmeshPetscCall(PetscObjectSetName((PetscObject)v, "Solution"));
294  LibmeshPetscCall(VecSetSizes(v, PETSC_DECIDE, n));
295  LibmeshPetscCall(VecSetFromOptions(v));
296  LibmeshPetscCall(VecZeroEntries(v));
297  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
298  }
PetscFunctionBegin
const double v
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ detectDeformation()

void SubChannel1PhaseProblem::detectDeformation ( )
protectedinherited

Detects whether pin diameter or duct displacement fields require geometry recalculation.

Definition at line 340 of file SubChannel1PhaseProblem.C.

Referenced by QuadSubChannel1PhaseProblem::initializeSolution(), and initializeSolution().

341 {
342  const Real tol = libMesh::TOLERANCE;
343  const auto pin_diameter = _subchannel_mesh.getPinDiameter();
344 
345  if (_pin_mesh_exist)
346  {
347  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
348  for (unsigned int i_pin = 0; i_pin < _n_pins; i_pin++)
349  {
350  auto * node = _subchannel_mesh.getPinNode(i_pin, iz);
351  const Real Dpin = (*_Dpin_soln)(node);
352  if (std::abs(Dpin) <= tol)
353  mooseError("Dpin is zero at node ",
354  node->id(),
355  ". You must initialize Dpin to a non-zero value.");
356  if (std::abs(Dpin - pin_diameter) > tol)
357  _deformation = true;
358  }
359  }
360 
361  for (unsigned int iz = 0; iz < _n_cells + 1 && !_deformation; iz++)
362  for (unsigned int i_ch = 0; i_ch < _n_channels && !_deformation; i_ch++)
363  {
364  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
365  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
366 
367  if ((subch_type == EChannelType::CORNER || subch_type == EChannelType::EDGE) &&
368  std::abs((*_displacement_soln)(node)) > tol)
369  _deformation = true;
370  }
371 }
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
virtual const Real & getPinDiameter() const
Return undeformed Pin diameter.
static constexpr Real TOLERANCE
const double tol
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
virtual Node * getPinNode(unsigned int i_pin, unsigned int iz) const =0
Get the pin mesh node for a given pin index and elevation index.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
bool _deformation
Flag that activates the effect of deformation (pin/duct) based on the auxvalues for displacement...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< SolutionHandle > _displacement_soln
void mooseError(Args &&... args) const

◆ externalSolve()

void SubChannel1PhaseProblem::externalSolve ( )
overridevirtualinherited

Assigning temperatures to duct

Implements ExternalProblem.

Definition at line 2518 of file SubChannel1PhaseProblem.C.

2519 {
2520  _console << "Executing subchannel solver\n";
2521  _dt = (isTransient() ? dt() : _one);
2522  _TR = isTransient();
2523 
2524  // The subchannel solver hardcodes a first-order backward (implicit) Euler time discretization, so
2525  // any other time integrator a user selects is silently ignored. Warn once if one is requested.
2527  {
2528  _time_integrator_checked = true;
2529  if (isTransient())
2530  if (auto * transient = dynamic_cast<TransientBase *>(_app.getExecutioner()))
2531  for (const auto * ti : transient->getTimeIntegrators())
2532  if (!dynamic_cast<const ImplicitEuler *>(ti))
2533  mooseWarning("The subchannel solver always uses implicit (backward) Euler time "
2534  "integration; the requested '",
2535  ti->type(),
2536  "' time integrator is ignored.");
2537  }
2538 
2540  // Small helper functions to reduce repetition
2541  // Verbose print helper (no-op unless _verbose_subchannel is true)
2542  auto V = [&](const std::string & s)
2543  {
2544  if (_verbose_subchannel)
2545  _console << s << std::endl;
2546  };
2547  V("Solution initialized");
2548  Real P_error = 1.0;
2549  unsigned int P_it = 0;
2550  unsigned int P_it_max;
2551 
2552  if (_segregated_bool)
2553  P_it_max = 20 * _n_blocks;
2554  else
2555  P_it_max = 100;
2556 
2557  if ((_n_blocks == 1) && (_segregated_bool))
2558  P_it_max = 5;
2559 
2560  while ((P_error > _P_tol && P_it < P_it_max))
2561  {
2562  P_it += 1;
2563  if (P_it == P_it_max && _n_blocks != 1)
2564  {
2565  _console << "Reached maximum number of axial pressure iterations" << std::endl;
2566  _converged = false;
2567  }
2568  _console << "Solving Outer Iteration : " << P_it << std::endl;
2569  auto P_L2norm_old_axial = _P_soln->L2norm();
2570  for (unsigned int iblock = 0; iblock < _n_blocks; iblock++)
2571  {
2572  int last_level = (iblock + 1) * _block_size;
2573  int first_level = iblock * _block_size + 1;
2574  Real T_block_error = 1.0;
2575  auto T_it = 0;
2576  _console << "Solving Block: " << iblock << " From first level: " << first_level
2577  << " to last level: " << last_level << std::endl;
2578  while (T_block_error > _T_tol && T_it < _T_maxit)
2579  {
2580  T_it += 1;
2581  if (T_it == _T_maxit)
2582  {
2583  _console << "Reached maximum number of temperature iterations for block: " << iblock
2584  << std::endl;
2585  _converged = false;
2586  }
2587  auto T_L2norm_old_block = _T_soln->L2norm();
2588  // We are only computing quantities on rank 0
2589  if (processor_id() > 0)
2590  goto aux_close;
2591 
2592  if (_segregated_bool)
2593  {
2594  computeWijFromSolve(iblock);
2595  if (_compute_power)
2596  {
2597  computeh(iblock);
2598  computeT(iblock);
2599  }
2600  }
2601  else
2602  {
2603  LibmeshPetscCall(implicitPetscSolve(iblock));
2604  computeWijPrime(iblock);
2605  V("Done with main solve.");
2606  if (_compute_power)
2607  {
2608  computeh(iblock);
2609  computeT(iblock);
2610  }
2611  V("Done with thermal solve.");
2612  }
2613 
2614  V("Start updating thermophysical properties.");
2615  if (_compute_density)
2616  computeRho(iblock);
2617  if (_compute_viscosity)
2618  computeMu(iblock);
2619  V("Done updating thermophysical properties.");
2620 
2621  // We must do a global assembly to make sure data is parallel consistent before we do things
2622  // like compute L2 norms
2623  aux_close:
2624  _aux->solution().close();
2625 
2626  auto T_L2norm_new = _T_soln->L2norm();
2627  T_block_error =
2628  std::abs((T_L2norm_new - T_L2norm_old_block) / (T_L2norm_old_block + 1E-14));
2629  _console << "T_block_error: " << T_block_error << std::endl;
2630 
2631  // All processes must have the same iteration count
2632  comm().max(T_block_error);
2633  }
2634  }
2635  auto P_L2norm_new_axial = _P_soln->L2norm();
2636  P_error =
2637  std::abs((P_L2norm_new_axial - P_L2norm_old_axial) / (P_L2norm_old_axial + _P_out + 1E-14));
2638  _console << "P_error :" << P_error << std::endl;
2639  V("Iteration: " + std::to_string(P_it));
2640  V("Maximum iterations: " + std::to_string(P_it_max));
2641  }
2642  // update old crossflow matrix
2643  _Wij_old = _Wij;
2644  _console << "Finished executing subchannel solver\n";
2645 
2646  // set SumWij at the inlet equal to the one on the first axial level (for visualization purposes)
2647  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
2648  {
2649  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, 0);
2650  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, 1);
2651  _SumWij_soln->set(node_in, (*_SumWij_soln)(node_out)); // kg/sec
2652  }
2653 
2654  if (_pin_mesh_exist)
2655  {
2656  // Assign average HTC to subchannels. This is exact if all pins have the same diameter
2657  for (unsigned int iz = 0; iz < _n_cells + 1; ++iz)
2658  {
2659  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
2660  {
2661  const auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
2662  auto mu = (*_mu_soln)(node);
2663  auto S = (*_S_flow_soln)(node);
2664  auto w_perim = (*_w_perim_soln)(node);
2665  auto Dh_i = 4.0 * S / w_perim;
2666  auto Re = (((*_mdot_soln)(node) / S) * Dh_i / mu);
2667  auto k = _fp->k_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node));
2668  auto cp = _fp->cp_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node));
2669  auto Pr = (*_mu_soln)(node)*cp / k;
2670  // Create Friction structure
2671  _friction_args = FrictionStruct(i_ch, Re, S, w_perim);
2672 
2673  Real sumhw = 0.0;
2674  for (auto i_pin : _subchannel_mesh.getChannelPins(i_ch))
2675  {
2676  // Create nusselt number structure
2677  _nusselt_args = NusseltStruct(Re, Pr, i_pin, iz, i_ch);
2678 
2679  // Compute HTC
2681  }
2682 
2683  // Set HTC
2684  _HTC_soln->set(node, sumhw / _subchannel_mesh.getChannelPins(i_ch).size());
2685  }
2686  }
2687  _HTC_soln->close();
2688 
2689  _console << "Commencing calculation of Pin surface temperature \n";
2690  for (unsigned int i_pin = 0; i_pin < _n_pins; i_pin++)
2691  {
2692  for (unsigned int iz = 0; iz < _n_cells + 1; ++iz)
2693  {
2694  const auto * pin_node = _subchannel_mesh.getPinNode(i_pin, iz);
2695  Real sumTemp = 0.0;
2696  // Calculate sum of pin surface temperatures that the channels around the pin see
2697  for (auto i_ch : _subchannel_mesh.getPinChannels(i_pin))
2698  {
2699  const auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
2700  auto mu = (*_mu_soln)(node);
2701  auto S = (*_S_flow_soln)(node);
2702  auto w_perim = (*_w_perim_soln)(node);
2703  auto Dh_i = 4.0 * S / w_perim;
2704  auto Re = (((*_mdot_soln)(node) / S) * Dh_i / mu);
2705  auto k = _fp->k_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node));
2706  auto cp = _fp->cp_from_p_T((*_P_soln)(node) + _P_out, (*_T_soln)(node));
2707  auto Pr = (*_mu_soln)(node)*cp / k;
2708  // Create Friction structure
2709  _friction_args = FrictionStruct(i_ch, Re, S, w_perim);
2710  // Create nusselt number structure
2711  _nusselt_args = NusseltStruct(Re, Pr, i_pin, iz, i_ch);
2712  // Compute HTC
2714  // Compute surface temperature contribution from subchannel side
2715  sumTemp +=
2716  (*_q_prime_soln)(pin_node) / ((*_Dpin_soln)(pin_node)*M_PI * hw) + (*_T_soln)(node);
2717  }
2718  if (_subchannel_mesh.getPinChannels(i_pin).size() > 0)
2719  _Tpin_soln->set(pin_node, sumTemp / _subchannel_mesh.getPinChannels(i_pin).size());
2720  else
2721  mooseError("Pin was not found for pin index: " + std::to_string(i_pin));
2722  }
2723  }
2724  }
2725 
2727  if (_duct_mesh_exist && processor_id() == 0)
2728  {
2729  _console << "Commencing calculation of duct surface temperature " << std::endl;
2730  auto duct_nodes = _subchannel_mesh.getDuctNodes();
2731  for (Node * dn : duct_nodes)
2732  {
2733  auto * node_chan = _subchannel_mesh.getChannelNodeFromDuct(dn);
2734  auto mu = (*_mu_soln)(node_chan);
2735  auto S = (*_S_flow_soln)(node_chan);
2736  auto w_perim = (*_w_perim_soln)(node_chan);
2737  auto Dh_i = 4.0 * S / w_perim;
2738  auto Re = (((*_mdot_soln)(node_chan) / S) * Dh_i / mu);
2739  auto k = _fp->k_from_p_T((*_P_soln)(node_chan) + _P_out, (*_T_soln)(node_chan));
2740  auto cp = _fp->cp_from_p_T((*_P_soln)(node_chan) + _P_out, (*_T_soln)(node_chan));
2741  auto Pr = (*_mu_soln)(node_chan)*cp / k;
2742 
2743  // Create nusselt number structure (consistent with pin case)
2744  const libMesh::Point & node_point = *_subchannel_mesh.getChannelNodeFromDuct(dn);
2745  const unsigned int iz = _subchannel_mesh.getZIndex(node_point);
2746  const unsigned int i_ch = _subchannel_mesh.channelIndex(node_point);
2747 
2748  // Create nusselt number structure
2749  _nusselt_args = NusseltStruct(Re, Pr, std::numeric_limits<unsigned int>::max(), iz, i_ch);
2750 
2751  // Create Friction structure
2752  _friction_args = FrictionStruct(i_ch, Re, S, w_perim);
2753 
2754  // Compute HTC
2756 
2757  // Compute Channel Temperature
2758  auto T_chan = (*_duct_heat_flux_soln)(dn) / hw + (*_T_soln)(node_chan);
2759  _Tduct_soln->set(dn, T_chan);
2760  }
2761  }
2762  _aux->solution().close();
2763  _aux->update();
2764 
2765  if (processor_id() != 0)
2766  return;
2767  Real power_in = 0.0;
2768  Real power_out = 0.0;
2769  Real viscosity_in = 0.0;
2770  Real mass_flow_in = 0.0;
2771  Real mass_flow_out = 0.0;
2772  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
2773  {
2774  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, 0);
2775  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, _n_cells);
2776  const Real mdot_in = (*_mdot_soln)(node_in);
2777  power_in += mdot_in * (*_h_soln)(node_in);
2778  power_out += (*_mdot_soln)(node_out) * (*_h_soln)(node_out);
2779  viscosity_in += mdot_in * (*_mu_soln)(node_in);
2780  mass_flow_in += mdot_in;
2781  mass_flow_out += (*_mdot_soln)(node_out);
2782  }
2783  auto h_bulk_out = power_out / mass_flow_out;
2784  auto T_bulk_out = _fp->T_from_p_h(_P_out, h_bulk_out);
2785 
2787  Real inlet_mu = viscosity_in / mass_flow_in;
2788  Real bulk_Re = mass_flow_in * bulk_Dh / (inlet_mu * _subchannel_mesh.getAssemblyFlowArea());
2789  if (_verbose_subchannel)
2790  {
2791  _console << " ======================================= " << std::endl;
2792  _console << " ======== Subchannel Print Outs ======== " << std::endl;
2793  _console << " ======================================= " << std::endl;
2794  _console << "Total flow area :" << _subchannel_mesh.getAssemblyFlowArea() << " m^2"
2795  << std::endl;
2796  _console << "Assembly hydraulic diameter :" << bulk_Dh << " m" << std::endl;
2797  _console << "Assembly Re number :" << bulk_Re << " [-]" << std::endl;
2798  _console << "Bulk coolant temperature at outlet :" << T_bulk_out << " K" << std::endl;
2799  _console << "Power added to coolant is : " << power_out - power_in << " Watt" << std::endl;
2800  _console << "Mass flow rate in is : " << mass_flow_in << " kg/sec" << std::endl;
2801  _console << "Mass balance is : " << mass_flow_out - mass_flow_in << " kg/sec" << std::endl;
2802  _console << "User defined outlet pressure is : " << _P_out << " Pa" << std::endl;
2803  _console << " ======================================= " << std::endl;
2804  }
2805 
2806  if (MooseUtils::absoluteFuzzyLessEqual((power_out - power_in), -1.0))
2807  mooseWarning(
2808  "Energy conservation equation might not be solved correctly, Power added to coolant: " +
2809  std::to_string(power_out - power_in) + " Watt ");
2810 }
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
void computeRho(int iblock)
Computes Density per channel for block iblock.
std::unique_ptr< SolutionHandle > _Tduct_soln
unsigned int _n_blocks
number of axial blocks
const bool _compute_power
Flag that informs if we need to solve the Enthalpy/Temperature equations or not.
std::unique_ptr< SolutionHandle > _T_soln
std::unique_ptr< SolutionHandle > _h_soln
virtual const std::vector< unsigned int > & getPinChannels(unsigned int i_pin) const =0
Return a vector of channel indices for a given Pin index.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
libMesh::DenseMatrix< Real > _Wij_old
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.
void computeT(int iblock)
Computes Temperature per channel for block iblock.
virtual const std::vector< unsigned int > & getChannelPins(unsigned int i_chan) const =0
Return a vector of pin indices for a given channel index.
const SCMHTCClosureBase * _pin_HTC_closure
HTC closure objects.
const bool _compute_density
Flag that activates or deactivates the calculation of density.
virtual Node * getPinNode(unsigned int i_pin, unsigned int iz) const =0
Get the pin mesh node for a given pin index and elevation index.
const Parallel::Communicator & comm() const
const bool _duct_mesh_exist
Flag that informs if there is a duct mesh or not.
const Real & _T_tol
Convergence tolerance for the temperature loop in internal solve.
void computeMu(int iblock)
Computes Viscosity per channel for block iblock.
Real getAssemblyHydraulicDiameter() const
Return undeformed bundle-average hydraulic diameter.
const bool _segregated_bool
Segregated solve.
bool _converged
Variable that informs whether we exited external solve with a converged solution or not...
virtual void initializeSolution()=0
Function to initialize the solution & geometry fields.
const SCMHTCClosureBase * _duct_HTC_closure
virtual void computeh(int iblock)=0
Computes Enthalpy per channel for block iblock.
static const std::string cp
Definition: NS.h:125
std::unique_ptr< SolutionHandle > _HTC_soln
const int & _T_maxit
Maximum iterations for the inner temperature loop.
const std::vector< Node * > & getDuctNodes() const
Function that returns the vector with the duct nodes.
bool _time_integrator_checked
Whether the time integrator has been checked for consistency with the implementation.
static const std::string S
Definition: NS.h:167
Node * getChannelNodeFromDuct(Node *duct_node) const
Function that gets the channel node from the duct node.
std::shared_ptr< AuxiliarySystem > _aux
const double Re
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _Dpin_soln
Real getAssemblyFlowArea() const
Return undeformed bundle inlet flow area.
Executioner * getExecutioner() const
virtual unsigned int channelIndex(const Point &point) const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const bool _compute_viscosity
Flag that activates or deactivates the calculation of viscosity.
MooseApp & _app
libMesh::DenseMatrix< Real > & _Wij
void max(const T &r, T &o, Request &req) const
void computeWijPrime(int iblock)
Computes turbulent crossflow per gap for block iblock.
std::unique_ptr< SolutionHandle > _SumWij_soln
void mooseWarning(Args &&... args) const
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
virtual void transient(bool trans)
void mooseError(Args &&... args) const
const Real & _P_tol
Convergence tolerance for the pressure loop in external solve.
struct SubChannel1PhaseProblem::FrictionStruct _friction_args
void computeWijFromSolve(int iblock)
Computes diversion crossflow per gap for block iblock.
const ConsoleStream _console
virtual bool isTransient() const override
PetscErrorCode implicitPetscSolve(int iblock)
Computes implicit solve using PetSc.
processor_id_type processor_id() const
const double mu
Real computeHTC(const FrictionStruct &friction_info, const NusseltStruct &nusselt_info, const Real conduction_k) const
Computes the convective heat transfer coefficient for the local conditions.
virtual Real & dt() const
std::unique_ptr< SolutionHandle > _P_soln
virtual unsigned int getZIndex(const Point &point) const
Get axial index of point.
static const std::string k
Definition: NS.h:134
struct SubChannel1PhaseProblem::NusseltStruct _nusselt_args
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.
std::unique_ptr< SolutionHandle > _Tpin_soln

◆ getAddedHeatDuct()

Real SubChannel1PhaseProblem::getAddedHeatDuct ( unsigned int  i_ch,
unsigned int  iz 
) const
inlineinherited

Return the added heat coming from the duct.

Definition at line 86 of file SubChannel1PhaseProblem.h.

87  {
88  return computeAddedHeatDuct(i_ch, iz);
89  }
virtual Real computeAddedHeatDuct(unsigned int i_ch, unsigned int iz) const
Non-pure: implemented in the base (or override in a child if needed)

◆ getAddedHeatPin()

Real SubChannel1PhaseProblem::getAddedHeatPin ( unsigned int  i_ch,
unsigned int  iz 
) const
inlineinherited

Return the added heat coming from the fuel pins.

Definition at line 80 of file SubChannel1PhaseProblem.h.

81  {
82  return computeAddedHeatPin(i_ch, iz);
83  }
virtual Real computeAddedHeatPin(unsigned int i_ch, unsigned int iz) const =0
Pure virtual: daughters provide different implementations.

◆ getDuctHTCClosure()

const SCMHTCClosureBase* SubChannel1PhaseProblem::getDuctHTCClosure ( ) const
inlineinherited

◆ getFrictionClosure()

const SCMFrictionClosureBase* SubChannel1PhaseProblem::getFrictionClosure ( ) const
inlineinherited

Definition at line 46 of file SubChannel1PhaseProblem.h.

Referenced by SCMMixingKimAndChung::computeLatticeMixingParameter(), and SCMHTCGnielinski::computeNusseltNumber().

46 { return _friction_closure; }
const SCMFrictionClosureBase * _friction_closure
Friction closure object.

◆ getOutletPressure()

const PostprocessorValue& SubChannel1PhaseProblem::getOutletPressure ( ) const
inlineinherited

Get outlet pressure.

Definition at line 95 of file SubChannel1PhaseProblem.h.

Referenced by SCMMixingKimAndChung::computeLatticeMixingParameter().

95 { return _P_out; }
const PostprocessorValue & _P_out
Outlet pressure postprocessor value.

◆ getPinHTCClosure()

const SCMHTCClosureBase* SubChannel1PhaseProblem::getPinHTCClosure ( ) const
inlineinherited

Definition at line 45 of file SubChannel1PhaseProblem.h.

45 { return _pin_HTC_closure; } // optional
const SCMHTCClosureBase * _pin_HTC_closure
HTC closure objects.

◆ getSinglePhaseFluidProperties()

const SinglePhaseFluidProperties* SubChannel1PhaseProblem::getSinglePhaseFluidProperties ( ) const
inlineinherited

Get fluid properties object.

Definition at line 101 of file SubChannel1PhaseProblem.h.

Referenced by SCMMixingKimAndChung::computeLatticeMixingParameter().

101 { return _fp; }
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.

◆ getSubChannelPeripheralDuctWidth()

Real TriSubChannel1PhaseProblem::getSubChannelPeripheralDuctWidth ( unsigned int  i_ch) const
overrideprotectedvirtual

Function that computes the width of the duct cell that the peripheral subchannel i_ch sees.

Implements SubChannel1PhaseProblem.

Definition at line 309 of file TriSubChannel1PhaseProblem.C.

310 {
311  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
312  if (subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER)
313  {
314  auto width = _subchannel_mesh.getPitch();
315  if (subch_type == EChannelType::CORNER)
316  width = 2.0 / std::sqrt(3.0) *
318  return width;
319  }
320  else
321  mooseError("Channel is not a perimetric subchannel ");
322 }
virtual const Real & getPinDiameter() const
Return undeformed Pin diameter.
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
const Real & getDuctToPinGap() const
Return the the gap thickness between the duct and peripheral fuel pins.
void mooseError(Args &&... args) const

◆ implicitPetscSolve()

PetscErrorCode SubChannel1PhaseProblem::implicitPetscSolve ( int  iblock)
protectedinherited

Computes implicit solve using PetSc.

Definition at line 2100 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::externalSolve().

2101 {
2103  // ---------- helper functions -----------------------------
2104  auto V = [&](const std::string & s)
2105  {
2106  if (_verbose_subchannel)
2107  _console << s << std::endl;
2108  };
2109 
2110  auto DupMatAssembled = [&](Mat src, Mat * dst)
2111  {
2112  if (src)
2113  {
2114  LibmeshPetscCall(MatDuplicate(src, MAT_COPY_VALUES, dst));
2115  LibmeshPetscCall(MatAssemblyBegin(*dst, MAT_FINAL_ASSEMBLY));
2116  LibmeshPetscCall(MatAssemblyEnd(*dst, MAT_FINAL_ASSEMBLY));
2117  }
2118  else
2119  *dst = NULL;
2120  };
2121 
2122  auto DupVecCopy = [&](Vec src, Vec * dst)
2123  {
2124  LibmeshPetscCall(VecDuplicate(src, dst));
2125  LibmeshPetscCall(VecCopy(src, *dst));
2126  };
2127 
2128  const PetscInt Q = 3; // [mass conservation, axial momentum, cross momentum]
2129 
2130  // small indexer
2131  auto Idx = [&](PetscInt r, PetscInt c) { return Q * r + c; };
2132 
2133  // arrays that MUST be declared before lambdas use them
2134  std::vector<Mat> mat_array(Q * Q, NULL);
2135  std::vector<Vec> vec_array(Q, NULL);
2136 
2137  // generic assembler for one governing equation row in the nested matrix
2138  auto AssembleEquation = [&](PetscInt f,
2139  Mat A0,
2140  Mat A1,
2141  Mat A2, // three blocks in row f (can be nullptr)
2142  Vec rhs, // base RHS for equation f
2143  Vec rhs_add, // optional extra RHS to add (can be nullptr)
2144  const char * label) // e.g. "Mass", "Lin mom", "Cross mom"
2145  {
2146  DupMatAssembled(A0, &mat_array[Idx(f, 0)]);
2147  DupMatAssembled(A1, &mat_array[Idx(f, 1)]);
2148  DupMatAssembled(A2, &mat_array[Idx(f, 2)]);
2149  DupVecCopy(rhs, &vec_array[f]);
2150  if (rhs_add)
2151  LibmeshPetscCall(VecAXPY(vec_array[f], 1.0, rhs_add));
2152  V(std::string(label) + " system assembled");
2153  };
2154 
2155  // -----------------------------------------------------------------------------
2156  // Helper lambda that applies per-equation under-relaxation by modifying BOTH the
2157  // matrix block and the RHS for that equation.
2158  //
2159  // Specifically, with A_ff for the equation and D = diag(A_ff):
2160  // 1) Matrix diagonal scaling: D <- D / alpha, then A_ff's diagonal is replaced
2161  // with D. For alpha < 1 this increases diagonal dominance (more damping).
2162  // 2) RHS blending with the previous solution x_old:
2163  // rhs_f <- rhs_f + (1 - alpha) * (D / alpha) * x_old
2164  // where x_old is provided by the caller via `populate(work)`.
2165  //
2166  // Net effect: the solved x satisfies
2167  // A_ff x = rhs_f_original + ((1 - alpha)/alpha) * D * (x_old - x),
2168  // which damps updates toward x_old without changing the converged solution.
2169  // -----------------------------------------------------------------------------
2170  auto RelaxEquation =
2171  [&](Mat A_ff, Vec rhs_f, Vec like_vec, Vec work, PetscScalar alpha, auto && populate)
2172  {
2173  Vec d = nullptr;
2174  LibmeshPetscCall(VecDuplicate(like_vec, &d));
2175 
2176  // 1) A_ff: diag <- diag / alpha
2177  LibmeshPetscCall(MatGetDiagonal(A_ff, d));
2178  LibmeshPetscCall(VecScale(d, 1.0 / alpha));
2179  LibmeshPetscCall(MatDiagonalSet(A_ff, d, INSERT_VALUES));
2180 
2181  // 2) work <- x_old (caller-provided populator)
2182  LibmeshPetscCall(populate(work));
2183 
2184  // 3) rhs_f += (1 - alpha) * (diag .* work)
2185  LibmeshPetscCall(VecScale(d, (1.0 - alpha)));
2186  LibmeshPetscCall(VecPointwiseMult(work, work, d));
2187  LibmeshPetscCall(VecAXPY(rhs_f, 1.0, work));
2188 
2189  LibmeshPetscCall(VecDestroy(&d));
2190  };
2191 
2192  // indices
2193  const unsigned int first_node = iblock * _block_size + 1;
2194  const unsigned int last_node = (iblock + 1) * _block_size;
2195 
2196  // ---------- assemble per-block operators -----------------
2197  computeSumWij(iblock);
2198  computeMdot(iblock);
2199  computeWijPrime(iblock);
2200  computeDP(iblock);
2201  computeP(iblock);
2202  computeWijResidual(iblock);
2203 
2204  V("Starting nested system.");
2205 
2206  // Populate nested matrix with the individual physics
2207  // equation 0: Mass conservation
2208  AssembleEquation(/*f=*/0,
2209  /*A0=*/_mc_axial_convection_mat,
2210  /*A1=*/nullptr,
2211  /*A2=*/_mc_sumWij_mat,
2212  /*rhs=*/_mc_axial_convection_rhs,
2213  /*rhs_add=*/nullptr,
2214  /*label=*/"Mass");
2215 
2216  // equation 1: Axial momentum conservation
2217  AssembleEquation(/*f=*/1,
2218  /*A0=*/_amc_sys_mdot_mat,
2219  /*A1=*/_amc_pressure_force_mat,
2220  /*A2=*/nullptr,
2221  /*rhs=*/_amc_pressure_force_rhs,
2222  /*rhs_add=*/_amc_sys_mdot_rhs,
2223  /*label=*/"Lin mom");
2224 
2225  // equation 2: Cross momentum conservation
2226  AssembleEquation(/*f=*/2,
2227  /*A0=*/nullptr,
2228  /*A1=*/_cmc_pressure_force_mat,
2229  /*A2=*/_cmc_sys_Wij_mat,
2230  /*rhs=*/_cmc_sys_Wij_rhs,
2231  /*rhs_add=*/_cmc_pressure_force_rhs,
2232  /*label=*/"Cross mom");
2233 
2234  // ========================== Relaxation ====================
2235  if (true)
2236  {
2237  LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2238  _prod, *_mdot_soln, first_node, last_node, _n_channels));
2239 
2240  Vec mdot_estimate;
2241  LibmeshPetscCall(createPetscVector(mdot_estimate, _block_size * _n_channels));
2242  Vec pmat_diag;
2243  LibmeshPetscCall(createPetscVector(pmat_diag, _block_size * _n_channels));
2244  Vec p_estimate;
2245  LibmeshPetscCall(createPetscVector(p_estimate, _block_size * _n_channels));
2246  Vec unity_vec;
2247  LibmeshPetscCall(createPetscVector(unity_vec, _block_size * _n_channels));
2248  LibmeshPetscCall(VecSet(unity_vec, 1.0));
2249  Vec sol_holder_P;
2250  LibmeshPetscCall(createPetscVector(sol_holder_P, _block_size * _n_gaps));
2251  Vec unity_vec_Wij;
2252  LibmeshPetscCall(createPetscVector(unity_vec_Wij, _block_size * _n_gaps));
2253  LibmeshPetscCall(VecSet(unity_vec_Wij, 1.0));
2254  Vec _Wij_loc_vec;
2255  LibmeshPetscCall(createPetscVector(_Wij_loc_vec, _block_size * _n_gaps));
2256  Vec _Wij_old_loc_vec;
2257  LibmeshPetscCall(createPetscVector(_Wij_old_loc_vec, _block_size * _n_gaps));
2258 
2259  // ---- scale estimates ----
2260  // mdot_estimate = A(1,0) * mdot
2261  LibmeshPetscCall(MatMult(mat_array[Q /* (1,0) */], _prod, mdot_estimate));
2262 
2263  // p_estimate = mdot_est / (diag(A(1,1)) + eps)
2264  LibmeshPetscCall(MatGetDiagonal(mat_array[Q + 1], pmat_diag));
2265  LibmeshPetscCall(VecAXPY(pmat_diag, 1e-10, unity_vec));
2266  LibmeshPetscCall(VecPointwiseDivide(p_estimate, mdot_estimate, pmat_diag));
2267 
2268  // sol_holder_P = A(2,1) * p_estimate - rhs_cmc_pressure
2269  LibmeshPetscCall(MatMult(mat_array[2 * Q + 1], p_estimate, sol_holder_P));
2270  LibmeshPetscCall(VecAXPY(sol_holder_P, -1.0, _cmc_pressure_force_rhs));
2271 
2272  // sumWij_loc from sol_holder_P (accumulate)
2273  Vec sumWij_loc;
2274  LibmeshPetscCall(createPetscVector(sumWij_loc, _block_size * _n_channels));
2275  for (unsigned int iz = first_node; iz <= last_node; ++iz)
2276  {
2277  const auto iz_ind = iz - first_node;
2278  for (unsigned int i_ch = 0; i_ch < _n_channels; ++i_ch)
2279  {
2280  PetscScalar sumWij = 0.0;
2281  unsigned int counter = 0;
2282  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
2283  {
2284  auto chans = _subchannel_mesh.getGapChannels(i_gap);
2285  unsigned int i_ch_loc = chans.first;
2286  PetscInt row_vec = i_ch_loc + _n_channels * iz_ind;
2287  PetscScalar loc_Wij_value;
2288  LibmeshPetscCall(VecGetValues(sol_holder_P, 1, &row_vec, &loc_Wij_value));
2289  sumWij += _subchannel_mesh.getCrossflowSign(i_ch, counter) * loc_Wij_value;
2290  counter++;
2291  }
2292  PetscInt row_vec = i_ch + _n_channels * iz_ind;
2293  LibmeshPetscCall(VecSetValues(sumWij_loc, 1, &row_vec, &sumWij, INSERT_VALUES));
2294  }
2295  }
2296  LibmeshPetscCall(VecAssemblyBegin(sumWij_loc));
2297  LibmeshPetscCall(VecAssemblyEnd(sumWij_loc));
2298 
2299  // ---- robust scale measurements ----
2300  PetscScalar min_mdot;
2301  LibmeshPetscCall(VecAbs(_prod));
2302  LibmeshPetscCall(VecMin(_prod, NULL, &min_mdot));
2303  V("Minimum estimated mdot: " + std::to_string(min_mdot));
2304 
2305  LibmeshPetscCall(VecAbs(sumWij_loc));
2306  LibmeshPetscCall(VecMax(sumWij_loc, NULL, &_max_sumWij));
2307  _max_sumWij = std::max(1e-10, _max_sumWij);
2308  V("Maximum estimated Wij: " + std::to_string(_max_sumWij));
2309 
2311  _Wij_loc_vec, _Wij, first_node, last_node, _n_gaps));
2312  LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2314  _Wij_old_loc_vec, _Wij_old, first_node, last_node, _n_gaps));
2315  LibmeshPetscCall(VecAbs(_Wij_old_loc_vec));
2316  LibmeshPetscCall(VecAXPY(_Wij_loc_vec, -1.0, _Wij_old_loc_vec));
2317 
2318  PetscScalar relax_factor;
2319  LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2320 #if !PETSC_VERSION_LESS_THAN(3, 16, 0)
2321  LibmeshPetscCall(VecMean(_Wij_loc_vec, &relax_factor));
2322 #else
2323  VecSum(_Wij_loc_vec, &relax_factor);
2324  relax_factor /= _block_size * _n_gaps;
2325 #endif
2326  relax_factor = relax_factor / _max_sumWij + 0.5;
2327  V("Relax base value: " + std::to_string(relax_factor));
2328 
2329  // ---- crossflow resistance inflation ----
2330  const PetscScalar resistance_relaxation = 0.9;
2331  _added_K = _max_sumWij / min_mdot;
2332  V("New cross resistance: " + std::to_string(_added_K));
2333  _added_K = (_added_K * resistance_relaxation + (1.0 - resistance_relaxation) * _added_K_old) *
2334  relax_factor;
2335  V("Relaxed cross resistance: " + std::to_string(_added_K));
2336 
2337  // Snap-up lower-bounding
2338  if (_added_K < 10 && _added_K >= 1.0)
2339  _added_K = 1.0;
2340  if (_added_K < 1.0 && _added_K >= 0.1)
2341  _added_K = 0.5;
2342  if (_added_K < 0.1 && _added_K >= 0.01)
2343  _added_K = 1. / 3.;
2344  if (_added_K < 1e-2 && _added_K >= 1e-3)
2345  _added_K = 0.1;
2346  V("Actual added cross resistance: " + std::to_string(_added_K));
2347  LibmeshPetscCall(VecScale(unity_vec_Wij, _added_K));
2349 
2350  LibmeshPetscCall(MatDiagonalSet(mat_array[2 * Q + 2], unity_vec_Wij, ADD_VALUES));
2351 
2352  // ---- cleanup temp vectors used above ----
2353  LibmeshPetscCall(VecDestroy(&mdot_estimate));
2354  LibmeshPetscCall(VecDestroy(&pmat_diag));
2355  LibmeshPetscCall(VecDestroy(&unity_vec));
2356  LibmeshPetscCall(VecDestroy(&p_estimate));
2357  LibmeshPetscCall(VecDestroy(&sol_holder_P));
2358  LibmeshPetscCall(VecDestroy(&unity_vec_Wij));
2359  LibmeshPetscCall(VecDestroy(&sumWij_loc));
2360  LibmeshPetscCall(VecDestroy(&_Wij_loc_vec));
2361  LibmeshPetscCall(VecDestroy(&_Wij_old_loc_vec));
2362 
2363  // ---- per-equation under-relaxation ----
2364  const PetscScalar relaxation_factor_mdot = 1.0;
2365  const PetscScalar relaxation_factor_P = 1.0;
2366  const PetscScalar relaxation_factor_Wij = 0.1;
2367 
2368  V("Relax mdot: " + std::to_string(relaxation_factor_mdot));
2369  V("Relax P: " + std::to_string(relaxation_factor_P));
2370  V("Relax Wij: " + std::to_string(relaxation_factor_Wij));
2371 
2372  // mdot
2373  RelaxEquation(mat_array[Idx(0, 0)],
2374  vec_array[0],
2375  vec_array[0],
2376  _prod,
2377  relaxation_factor_mdot,
2378  [&](Vec dst)
2379  {
2380  return populateVectorFromHandle<SolutionHandle>(
2381  dst, *_mdot_soln, first_node, last_node, _n_channels);
2382  });
2383  V("mdot relaxed");
2384 
2385  // pressure
2386  RelaxEquation(mat_array[Idx(1, 1)],
2387  vec_array[1],
2388  vec_array[1],
2389  _prod,
2390  relaxation_factor_P,
2391  [&](Vec dst)
2392  {
2393  return populateVectorFromHandle<SolutionHandle>(
2394  dst, *_P_soln, first_node, last_node, _n_channels);
2395  });
2396  V("P relaxed");
2397 
2398  // crossflow
2399  RelaxEquation(mat_array[Idx(2, 2)],
2400  vec_array[2],
2401  vec_array[2],
2402  _Wij_vec,
2403  relaxation_factor_Wij,
2404  [&](Vec dst)
2405  {
2406  return populateVectorFromDense<libMesh::DenseMatrix<Real>>(
2407  dst, _Wij, first_node, last_node, _n_gaps);
2408  });
2409  V("Wij relaxed");
2410  }
2411  V("Linear solver relaxed");
2412 
2413  // ======================== Create and configure KSP =========================
2414  Mat A_nest;
2415  Vec b_nest;
2416  Vec x_nest;
2417  LibmeshPetscCall(MatCreateNest(PETSC_COMM_SELF, Q, NULL, Q, NULL, mat_array.data(), &A_nest));
2418  LibmeshPetscCall(VecCreateNest(PETSC_COMM_SELF, Q, NULL, vec_array.data(), &b_nest));
2419  V("Nested system created");
2420 
2421  KSP ksp;
2422  PC pc;
2423  LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
2424  LibmeshPetscCall(KSPSetType(ksp, KSPFGMRES));
2425  LibmeshPetscCall(KSPSetOperators(ksp, A_nest, A_nest));
2426  LibmeshPetscCall(KSPGetPC(ksp, &pc));
2427  LibmeshPetscCall(PCSetType(pc, PCFIELDSPLIT));
2428  LibmeshPetscCall(KSPSetTolerances(ksp, _rtol, _atol, _dtol, _maxit));
2429 
2430  // split equations
2431  std::vector<IS> rows(Q);
2432  LibmeshPetscCall(MatNestGetISs(A_nest, rows.data(), NULL));
2433  for (PetscInt j = 0; j < Q; ++j)
2434  {
2435  IS part;
2436  LibmeshPetscCall(ISDuplicate(rows[j], &part));
2437  LibmeshPetscCall(PCFieldSplitSetIS(pc, NULL, part));
2438  LibmeshPetscCall(ISDestroy(&part));
2439  }
2440  V("Linear solver assembled");
2441 
2442  // ============================== Solve =====================================
2443  LibmeshPetscCall(VecDuplicate(b_nest, &x_nest));
2444  LibmeshPetscCall(VecSet(x_nest, 0.0));
2445  LibmeshPetscCall(KSPSolve(ksp, b_nest, x_nest));
2446 
2447  // destroy solver containers first
2448  LibmeshPetscCall(VecDestroy(&b_nest));
2449  LibmeshPetscCall(MatDestroy(&A_nest));
2450  LibmeshPetscCall(KSPDestroy(&ksp));
2451  for (PetscInt i = 0; i < Q * Q; i++)
2452  LibmeshPetscCall(MatDestroy(&mat_array[i]));
2453  for (PetscInt i = 0; i < Q; i++)
2454  LibmeshPetscCall(VecDestroy(&vec_array[i]));
2455  V("Solver elements destroyed");
2456 
2457  // ====================== Extract & scatter the solution =====================
2458  Vec sol_mdot, sol_p, sol_Wij;
2459  V("Vectors to hold solution created");
2460  PetscInt num_vecs;
2461  Vec * loc_vecs;
2462  LibmeshPetscCall(VecNestGetSubVecs(x_nest, &num_vecs, &loc_vecs));
2463  LibmeshPetscCall(VecDuplicate(_mc_axial_convection_rhs, &sol_mdot));
2464  LibmeshPetscCall(VecCopy(loc_vecs[0], sol_mdot));
2465  LibmeshPetscCall(VecDuplicate(_amc_sys_mdot_rhs, &sol_p));
2466  LibmeshPetscCall(VecCopy(loc_vecs[1], sol_p));
2467  LibmeshPetscCall(VecDuplicate(_cmc_sys_Wij_rhs, &sol_Wij));
2468  LibmeshPetscCall(VecCopy(loc_vecs[2], sol_Wij));
2469  V("Solution from coupled solver copied to solution vectors");
2470 
2471  // mass flow
2472  LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2473  sol_mdot, *_mdot_soln, first_node, last_node, _n_channels));
2474 
2475  // pressure
2476  {
2477  PetscScalar * sol_p_array;
2478  LibmeshPetscCall(VecGetArray(sol_p, &sol_p_array));
2479  for (unsigned int iz = last_node; iz > first_node - 1; iz--)
2480  {
2481  const auto iz_ind = iz - first_node;
2482  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
2483  {
2484  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
2485  PetscScalar value = sol_p_array[iz_ind * _n_channels + i_ch];
2486  _P_soln->set(node_in, value);
2487  }
2488  }
2489  LibmeshPetscCall(VecRestoreArray(sol_p, &sol_p_array));
2490  }
2491 
2492  // crossflow dense + sumWij + correction factor
2494  sol_Wij, _Wij, first_node, last_node, _n_gaps));
2495 
2496  LibmeshPetscCall(MatMult(_mc_sumWij_mat, sol_Wij, _prod));
2497  LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2498  _prod, *_SumWij_soln, first_node, last_node, _n_channels));
2499 
2500  LibmeshPetscCall(VecAbs(_prod));
2501  LibmeshPetscCall(VecMax(_prod, NULL, &_max_sumWij_new));
2502  V("Maximum estimated Wij new: " + std::to_string(_max_sumWij_new));
2504  V("Correction factor: " + std::to_string(_correction_factor));
2505  V("Solutions assigned to MOOSE variables.");
2506 
2507  // cleanup solution objects
2508  LibmeshPetscCall(VecDestroy(&x_nest));
2509  LibmeshPetscCall(VecDestroy(&sol_mdot));
2510  LibmeshPetscCall(VecDestroy(&sol_p));
2511  LibmeshPetscCall(VecDestroy(&sol_Wij));
2512  V("Solutions destroyed.");
2513 
2514  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
2515 }
Mat _amc_sys_mdot_mat
Axial momentum system matrix.
void computeSumWij(int iblock)
Computes net diversion crossflow per channel for block iblock.
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
void computeP(int iblock)
Computes Pressure per channel for block iblock.
libMesh::DenseMatrix< Real > _Wij_old
void computeMdot(int iblock)
Computes mass flow per channel for block iblock.
PetscScalar _added_K
Added resistances for monolithic convergence.
PetscErrorCode createPetscVector(Vec &v, PetscInt n)
Petsc Functions.
PetscFunctionBegin
Mat _cmc_sys_Wij_mat
Lateral momentum system matrix.
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
Mat _mc_sumWij_mat
Matrices and vectors to be used in implicit assembly Mass conservation Mass conservation - sum of cro...
PetscErrorCode populateVectorFromDense(Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
Mat _amc_pressure_force_mat
Axial momentum conservation - pressure force.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void computeWijResidual(int iblock)
Computes Residual Matrix based on the lateral momentum conservation equation for block iblock...
Real f(Real x)
Test function for Brents method.
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
Mat _mc_axial_convection_mat
Mass conservation - axial convection.
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
PetscErrorCode populateDenseFromVector(const Vec &x, T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
libMesh::DenseMatrix< Real > & _Wij
void computeWijPrime(int iblock)
Computes turbulent crossflow per gap for block iblock.
static const std::string alpha
Definition: NS.h:138
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a sign for the crossflow given a subchannel index and local neighbor index.
std::unique_ptr< SolutionHandle > _SumWij_soln
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const ConsoleStream _console
void computeDP(int iblock)
Computes Pressure Drop per channel for block iblock.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
Mat _cmc_pressure_force_mat
Cross momentum conservation - pressure force.
std::unique_ptr< SolutionHandle > _P_soln
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.

◆ initializeSolution()

void TriSubChannel1PhaseProblem::initializeSolution ( )
overrideprotectedvirtual

Function to initialize the solution & geometry fields.

Implements SubChannel1PhaseProblem.

Definition at line 69 of file TriSubChannel1PhaseProblem.C.

70 {
72 
73  if (_deformation)
74  {
75  // update surface area, wetted perimeter based on: Dpin, displacement
76  Real standard_area, wire_area, additional_area, wetted_perimeter, displaced_area;
77  auto flat_to_flat = _tri_sch_mesh.getFlatToFlat();
78  auto n_rings = _tri_sch_mesh.getNumOfRings();
80  auto pin_diameter = _subchannel_mesh.getPinDiameter();
81  auto wire_diameter = _tri_sch_mesh.getWireDiameter();
82  auto wire_lead_length = _tri_sch_mesh.getWireLeadLength();
83  auto gap = _tri_sch_mesh.getDuctToPinGap();
84  auto z_blockage = _subchannel_mesh.getZBlockage();
85  auto index_blockage = _subchannel_mesh.getIndexBlockage();
86  auto reduction_blockage = _subchannel_mesh.getReductionBlockage();
87  auto theta =
88  std::acos(wire_lead_length /
89  std::sqrt(Utility::pow<2>(wire_lead_length) +
90  Utility::pow<2>(libMesh::pi * (pin_diameter + wire_diameter))));
91  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
92  {
93  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
94  {
95  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
96  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
97  auto Z = _z_grid[iz];
98  Real rod_area = 0.0;
99  Real rod_perimeter = 0.0;
100  for (auto i_pin : _subchannel_mesh.getChannelPins(i_ch))
101  {
102  auto * pin_node = _subchannel_mesh.getPinNode(i_pin, iz);
103  if (subch_type == EChannelType::CENTER || subch_type == EChannelType::CORNER)
104  {
105  rod_area +=
106  (1.0 / 6.0) * 0.25 * M_PI * (*_Dpin_soln)(pin_node) * (*_Dpin_soln)(pin_node);
107  rod_perimeter += (1.0 / 6.0) * M_PI * (*_Dpin_soln)(pin_node);
108  }
109  else
110  {
111  rod_area +=
112  (1.0 / 4.0) * 0.25 * M_PI * (*_Dpin_soln)(pin_node) * (*_Dpin_soln)(pin_node);
113  rod_perimeter += (1.0 / 4.0) * M_PI * (*_Dpin_soln)(pin_node);
114  }
115  }
116 
117  if (subch_type == EChannelType::CENTER)
118  {
119  standard_area = Utility::pow<2>(pitch) * std::sqrt(3.0) / 4.0;
120  additional_area = 0.0;
121  displaced_area = 0.0;
122  wire_area = libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
123  wetted_perimeter = rod_perimeter + 0.5 * libMesh::pi * wire_diameter / std::cos(theta);
124  }
125  else if (subch_type == EChannelType::EDGE)
126  {
127  standard_area = pitch * (pin_diameter / 2.0 + gap);
128  additional_area = 0.0;
129  displaced_area = (*_displacement_soln)(node)*pitch;
130  wire_area = libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
131  wetted_perimeter =
132  rod_perimeter + 0.5 * libMesh::pi * wire_diameter / std::cos(theta) + pitch;
133  }
134  else
135  {
136  standard_area = 1.0 / std::sqrt(3.0) * Utility::pow<2>(pin_diameter / 2.0 + gap);
137  additional_area = 0.0;
138  displaced_area = 1.0 / std::sqrt(3.0) *
139  (pin_diameter + 2.0 * gap + (*_displacement_soln)(node)) *
140  (*_displacement_soln)(node);
141  wire_area = libMesh::pi / 24.0 * Utility::pow<2>(wire_diameter) / std::cos(theta);
142  wetted_perimeter =
143  rod_perimeter + libMesh::pi * wire_diameter / std::cos(theta) / 6.0 +
144  2.0 / std::sqrt(3.0) * (pin_diameter / 2.0 + gap + (*_displacement_soln)(node));
145  }
146 
147  // Calculate subchannel area
148  auto subchannel_area =
149  standard_area + additional_area + displaced_area - rod_area - wire_area;
150 
151  // Correct subchannel area and wetted perimeter in case of overlapping pins
152  auto overlapping_pin_area = 0.0;
153  auto overlapping_wetted_perimeter = 0.0;
154  for (auto i_gap : _subchannel_mesh.getChannelGaps(i_ch))
155  {
156  auto gap_pins = _subchannel_mesh.getGapPins(i_gap);
157  auto pin_1 = gap_pins.first;
158  auto pin_2 = gap_pins.second;
159  auto * pin_node_1 = _subchannel_mesh.getPinNode(pin_1, iz);
160  auto * pin_node_2 = _subchannel_mesh.getPinNode(pin_2, iz);
161  auto Diameter1 = (*_Dpin_soln)(pin_node_1);
162  auto Radius1 = Diameter1 / 2.0;
163  auto Diameter2 = (*_Dpin_soln)(pin_node_2);
164  auto Radius2 = Diameter2 / 2.0;
166 
167  if (pitch < (Radius1 + Radius2)) // overlapping pins
168  {
169  mooseWarning(" The gap of index : '", i_gap, " at axial cell ", iz, " ' is blocked.");
170  auto cos1 =
171  (pitch * pitch + Radius1 * Radius1 - Radius2 * Radius2) / (2 * pitch * Radius1);
172  auto cos2 =
173  (pitch * pitch + Radius2 * Radius2 - Radius1 * Radius1) / (2 * pitch * Radius2);
174  auto angle1 = 2.0 * acos(cos1);
175  auto angle2 = 2.0 * acos(cos2);
176  // half of the intersecting arc-length
177  overlapping_wetted_perimeter += 0.5 * angle1 * Radius1 + 0.5 * angle2 * Radius2;
178  // Half of the overlapping area
179  overlapping_pin_area +=
180  0.5 * Radius1 * Radius1 * acos(cos1) + 0.5 * Radius2 * Radius2 * acos(cos2) -
181  0.25 * sqrt((-pitch + Radius1 + Radius2) * (pitch + Radius1 - Radius2) *
182  (pitch - Radius1 + Radius2) * (pitch + Radius1 + Radius2));
183  }
184  }
185  subchannel_area += overlapping_pin_area; // correct surface area
186  wetted_perimeter += -overlapping_wetted_perimeter; // correct wetted perimeter
187 
188  // Apply area reduction on subchannels affected by blockage
189  auto index = 0;
190  for (const auto & i_blockage : index_blockage)
191  {
192  if (i_ch == i_blockage && (Z >= z_blockage.front() && Z <= z_blockage.back()))
193  {
194  subchannel_area *= reduction_blockage[index];
195  }
196  index++;
197  }
198  _S_flow_soln->set(node, subchannel_area);
199  _w_perim_soln->set(node, wetted_perimeter);
200  }
201  }
202  // update map of gap between pins (gij) based on: Dpin, displacement
203  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
204  {
205  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
206  {
207  auto gap_pins = _subchannel_mesh.getGapPins(i_gap);
208  auto pin_1 = gap_pins.first;
209  auto pin_2 = gap_pins.second;
210  auto * pin_node_1 = _subchannel_mesh.getPinNode(pin_1, iz);
211  auto * pin_node_2 = _subchannel_mesh.getPinNode(pin_2, iz);
212 
213  if (pin_1 == pin_2) // Corner or edge gap
214  {
215  auto displacement = 0.0;
216  auto counter = 0.0;
217  for (auto i_ch : _subchannel_mesh.getPinChannels(pin_1))
218  {
219  auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
220  auto * node = _subchannel_mesh.getChannelNode(i_ch, iz);
221  if (subch_type == EChannelType::EDGE || subch_type == EChannelType::CORNER)
222  {
223  displacement += (*_displacement_soln)(node);
224  counter += 1.0;
225  }
226  }
227  displacement = displacement / counter;
229  i_gap,
230  0.5 * (flat_to_flat - (n_rings - 1) * pitch * std::sqrt(3.0) -
231  (*_Dpin_soln)(pin_node_1)) +
232  displacement);
233  }
234  else // center gap
235  {
237  iz, i_gap, pitch - (*_Dpin_soln)(pin_node_1) / 2.0 - (*_Dpin_soln)(pin_node_2) / 2.0);
238  }
239  // if pins come in contact, the gap is zero
240  if (_tri_sch_mesh.getGapWidth(iz, i_gap) <= 0.0)
241  _tri_sch_mesh.setGapWidth(iz, i_gap, 0.0);
242  }
243  }
244  }
245 
246  for (unsigned int iz = 1; iz < _n_cells + 1; iz++)
247  {
248  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
249  {
250  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
251  auto * node_in = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
252  _mdot_soln->set(node_out, (*_mdot_soln)(node_in));
253  }
254  }
255 
256  // We must do a global assembly to make sure data is parallel consistent before we do things
257  // like compute L2 norms
258  _aux->solution().close();
259 }
const Real & getWireDiameter() const
Return wire diameter.
virtual const std::pair< unsigned int, unsigned int > & getGapPins(unsigned int i_gap) const =0
Return a pair of pin indices for a given gap index.
virtual const Real & getPinDiameter() const
Return undeformed Pin diameter.
virtual const std::vector< unsigned int > & getPinChannels(unsigned int i_pin) const =0
Return a vector of channel indices for a given Pin index.
void setGapWidth(unsigned int axial_index, unsigned int gap_index, Real gap_width)
Set the gap width for a given axial cell and gap index.
virtual const std::vector< unsigned int > & getChannelPins(unsigned int i_chan) const =0
Return a vector of pin indices for a given channel index.
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
std::unique_ptr< SolutionHandle > _S_flow_soln
virtual Node * getPinNode(unsigned int i_pin, unsigned int iz) const =0
Get the pin mesh node for a given pin index and elevation 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.
const unsigned int & getNumOfRings() const
Return the number of fuel-pin rings, counting the center pin as the first ring.
const Real & getDuctToPinGap() const
Return the the gap thickness between the duct and peripheral fuel pins.
std::vector< Real > _z_grid
axial location of nodes
static const std::string pitch
std::shared_ptr< AuxiliarySystem > _aux
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _Dpin_soln
bool _deformation
Flag that activates the effect of deformation (pin/duct) based on the auxvalues for displacement...
virtual const std::vector< Real > & getReductionBlockage() const
Get area reduction of blocked subchannels.
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
const Real & getFlatToFlat() const
Return flat to flat [m].
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const std::vector< Real > & getZBlockage() const
Get axial location of blockage (in,out) [m].
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
void detectDeformation()
Detects whether pin diameter or duct displacement fields require geometry recalculation.
Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const override
Return gap width for a given gap index.
void mooseWarning(Args &&... args) const
virtual const std::vector< unsigned int > & getIndexBlockage() const
Get index of blocked subchannels.
const Real & getWireLeadLength() const
Return the wire lead length.
std::unique_ptr< SolutionHandle > _w_perim_soln
const Real pi

◆ initialSetup()

void SubChannel1PhaseProblem::initialSetup ( )
overridevirtualinherited

Set value for turbulent momentum modeling parameter CT

Reimplemented from ExternalProblem.

Definition at line 289 of file SubChannel1PhaseProblem.C.

290 {
292 
293  _fp = &getUserObject<SinglePhaseFluidProperties>(getParam<UserObjectName>("fp"));
295  &getUserObject<SCMFrictionClosureBase>(getParam<UserObjectName>("friction_closure"));
297  &getUserObject<SCMMixingClosureBase>(getParam<UserObjectName>("mixing_closure"));
298 
301 
302  // Create variables for output and storage
303  _mdot_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::MASS_FLOW_RATE));
304  _SumWij_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::SUM_CROSSFLOW));
305  _P_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::PRESSURE));
306  if (getParam<bool>("full_output"))
307  {
308  _DP_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::PRESSURE_DROP));
309  _ff_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::FRICTION_FACTOR));
310  }
311  _h_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::ENTHALPY));
312  _T_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::TEMPERATURE));
313  if (_pin_mesh_exist)
314  {
315  _Tpin_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::PIN_TEMPERATURE));
316  _Dpin_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::PIN_DIAMETER));
317  _HTC_soln =
318  std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::HEAT_TRANSFER_COEFFICIENT));
320  &getUserObject<SCMHTCClosureBase>(getParam<UserObjectName>("pin_HTC_closure"));
321  }
322  _rho_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::DENSITY));
323  _mu_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::VISCOSITY));
324  _S_flow_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::SURFACE_AREA));
325  _w_perim_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::WETTED_PERIMETER));
326  _q_prime_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::LINEAR_HEAT_RATE));
328  std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::DISPLACEMENT));
329  if (_duct_mesh_exist)
330  {
332  std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::DUCT_HEAT_FLUX));
333  _Tduct_soln = std::make_unique<SolutionHandle>(getVariable(0, SubChannelApp::DUCT_TEMPERATURE));
335  &getUserObject<SCMHTCClosureBase>(getParam<UserObjectName>("duct_HTC_closure"));
336  }
337 }
static const std::string PRESSURE_DROP
Definition: SubChannelApp.h:32
static const std::string FRICTION_FACTOR
Definition: SubChannelApp.h:44
static const std::string MASS_FLOW_RATE
Definition: SubChannelApp.h:28
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
std::unique_ptr< SolutionHandle > _Tduct_soln
std::unique_ptr< SolutionHandle > _duct_heat_flux_soln
static const std::string DENSITY
Definition: SubChannelApp.h:37
std::unique_ptr< SolutionHandle > _T_soln
std::unique_ptr< SolutionHandle > _h_soln
std::unique_ptr< SolutionHandle > _S_flow_soln
const SCMHTCClosureBase * _pin_HTC_closure
HTC closure objects.
static const std::string PIN_DIAMETER
Definition: SubChannelApp.h:36
const SCMMixingClosureBase * _mixing_closure
Turbulent Mixing closure object.
const bool _duct_mesh_exist
Flag that informs if there is a duct mesh or not.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
static const std::string DUCT_HEAT_FLUX
Definition: SubChannelApp.h:41
static const std::string DUCT_TEMPERATURE
Definition: SubChannelApp.h:42
const SCMHTCClosureBase * _duct_HTC_closure
static const std::string WETTED_PERIMETER
Definition: SubChannelApp.h:39
std::unique_ptr< SolutionHandle > _rho_soln
static const std::string VISCOSITY
Definition: SubChannelApp.h:38
std::unique_ptr< SolutionHandle > _HTC_soln
static const std::string PIN_TEMPERATURE
Definition: SubChannelApp.h:35
static const std::string LINEAR_HEAT_RATE
Definition: SubChannelApp.h:40
std::unique_ptr< SolutionHandle > _q_prime_soln
static const std::string ENTHALPY
Definition: SubChannelApp.h:33
void initialSetup() override
virtual Real getCT() const
Return the Turbulent modeling parameter.
const SCMFrictionClosureBase * _friction_closure
Friction closure object.
std::unique_ptr< SolutionHandle > _Dpin_soln
std::unique_ptr< SolutionHandle > _mdot_soln
Solutions handles and link to TH tables properties.
static const std::string SUM_CROSSFLOW
Definition: SubChannelApp.h:30
std::unique_ptr< SolutionHandle > _displacement_soln
std::unique_ptr< SolutionHandle > _DP_soln
static const std::string PRESSURE
Definition: SubChannelApp.h:31
std::unique_ptr< SolutionHandle > _SumWij_soln
static const std::string SURFACE_AREA
Definition: SubChannelApp.h:29
Real _CT
Turbulent modeling parameter used in axial momentum equation.
std::unique_ptr< SolutionHandle > _ff_soln
static const std::string HEAT_TRANSFER_COEFFICIENT
Definition: SubChannelApp.h:45
static const std::string DISPLACEMENT
Definition: SubChannelApp.h:43
static const std::string TEMPERATURE
Definition: SubChannelApp.h:34
std::unique_ptr< SolutionHandle > _P_soln
std::unique_ptr< SolutionHandle > _w_perim_soln
const SinglePhaseFluidProperties * _fp
Non-owning pointer to fluid properties user object.
std::unique_ptr< SolutionHandle > _mu_soln
std::unique_ptr< SolutionHandle > _Tpin_soln

◆ petscSnesSolver()

PetscErrorCode SubChannel1PhaseProblem::petscSnesSolver ( int  iblock,
const libMesh::DenseVector< Real > &  solution,
libMesh::DenseVector< Real > &  root 
)
protectedinherited

Computes solution of nonlinear equation using snes and provided a residual in a formFunction.

Definition at line 1969 of file SubChannel1PhaseProblem.C.

Referenced by SubChannel1PhaseProblem::computeWijFromSolve().

1972 {
1973  SNES snes;
1974  KSP ksp;
1975  PC pc;
1976  Vec x, r;
1977  PetscScalar * xx;
1978 
1980  LibmeshPetscCall(SNESCreate(PETSC_COMM_SELF, &snes));
1981  LibmeshPetscCall(VecCreate(PETSC_COMM_SELF, &x));
1982  LibmeshPetscCall(VecSetSizes(x, PETSC_DECIDE, _block_size * _n_gaps));
1983  LibmeshPetscCall(VecSetFromOptions(x));
1984  LibmeshPetscCall(VecDuplicate(x, &r));
1985 
1986 #if PETSC_VERSION_LESS_THAN(3, 13, 0)
1987  LibmeshPetscCall(PetscOptionsSetValue(PETSC_NULL, "-snes_mf", PETSC_NULL));
1988 #else
1989  LibmeshPetscCall(SNESSetUseMatrixFree(snes, PETSC_FALSE, PETSC_TRUE));
1990 #endif
1991  Ctx ctx;
1992  ctx.iblock = iblock;
1993  ctx.schp = this;
1994  LibmeshPetscCall(SNESSetFunction(snes, r, formFunction, &ctx));
1995  LibmeshPetscCall(SNESGetKSP(snes, &ksp));
1996  LibmeshPetscCall(KSPGetPC(ksp, &pc));
1997  LibmeshPetscCall(PCSetType(pc, PCNONE));
1998  LibmeshPetscCall(KSPSetTolerances(ksp, _rtol, _atol, _dtol, _maxit));
1999  LibmeshPetscCall(SNESSetFromOptions(snes));
2000  LibmeshPetscCall(VecGetArray(x, &xx));
2001  for (unsigned int i = 0; i < _block_size * _n_gaps; i++)
2002  {
2003  xx[i] = solution(i);
2004  }
2005  LibmeshPetscCall(VecRestoreArray(x, &xx));
2006 
2007  LibmeshPetscCall(SNESSolve(snes, NULL, x));
2008  LibmeshPetscCall(VecGetArray(x, &xx));
2009  for (unsigned int i = 0; i < _block_size * _n_gaps; i++)
2010  root(i) = xx[i];
2011 
2012  LibmeshPetscCall(VecRestoreArray(x, &xx));
2013  LibmeshPetscCall(VecDestroy(&x));
2014  LibmeshPetscCall(VecDestroy(&r));
2015  LibmeshPetscCall(SNESDestroy(&snes));
2016  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
2017 }
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
PetscFunctionBegin
const std::vector< double > x
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent&#39;s method.
Definition: BrentsMethod.C:66
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
friend PetscErrorCode formFunction(SNES snes, Vec x, Vec f, void *ctx)
This is the residual Vector function in a form compatible with the SNES PETC solvers.
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
void * ctx
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ populateDenseFromVector()

template<class T >
PetscErrorCode SubChannel1PhaseProblem::populateDenseFromVector ( const Vec &  x,
T solution,
const unsigned int  first_axial_level,
const unsigned int  last_axial_level,
const unsigned int  cross_dimension 
)
protectedinherited

Definition at line 420 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeWijPrime(), and SubChannel1PhaseProblem::implicitPetscSolve().

425 {
426  PetscScalar * xx;
427 
429  LibmeshPetscCall(VecGetArray(x, &xx));
430  for (unsigned int iz = first_axial_level; iz < last_axial_level + 1; iz++)
431  {
432  unsigned int iz_ind = iz - first_axial_level;
433  for (unsigned int i_l = 0; i_l < cross_dimension; i_l++)
434  {
435  loc_solution(i_l, iz) = xx[iz_ind * cross_dimension + i_l];
436  }
437  }
438  LibmeshPetscCall(VecRestoreArray(x, &xx));
439 
440  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
441 }
PetscFunctionBegin
const std::vector< double > x
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ populateSolutionChan()

template<class T >
PetscErrorCode SubChannel1PhaseProblem::populateSolutionChan ( const Vec &  x,
T solution,
const unsigned int  first_axial_level,
const unsigned int  last_axial_level,
const unsigned int  cross_dimension 
)
protectedinherited

Definition at line 494 of file SubChannel1PhaseProblem.h.

499 {
500  PetscScalar * xx;
502  LibmeshPetscCall(VecGetArray(x, &xx));
503  Node * loc_node;
504  for (unsigned int iz = first_axial_level; iz < last_axial_level + 1; iz++)
505  {
506  unsigned int iz_ind = iz - first_axial_level;
507  for (unsigned int i_l = 0; i_l < cross_dimension; i_l++)
508  {
509  loc_node = _subchannel_mesh.getChannelNode(i_l, iz);
510  loc_solution.set(loc_node, xx[iz_ind * cross_dimension + i_l]);
511  }
512  }
513  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
514 }
PetscFunctionBegin
const std::vector< double > x
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ populateVectorFromDense()

template<class T >
PetscErrorCode SubChannel1PhaseProblem::populateVectorFromDense ( Vec &  x,
const T solution,
const unsigned int  first_axial_level,
const unsigned int  last_axial_level,
const unsigned int  cross_dimension 
)
protectedinherited

Definition at line 471 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeSumWij(), SubChannel1PhaseProblem::computeWijResidual(), and SubChannel1PhaseProblem::implicitPetscSolve().

476 {
477  PetscScalar * xx;
479  LibmeshPetscCall(VecGetArray(x, &xx));
480  for (unsigned int iz = first_axial_level; iz < last_axial_level + 1; iz++)
481  {
482  unsigned int iz_ind = iz - first_axial_level;
483  for (unsigned int i_l = 0; i_l < cross_dimension; i_l++)
484  {
485  xx[iz_ind * cross_dimension + i_l] = loc_solution(i_l, iz);
486  }
487  }
488  LibmeshPetscCall(VecRestoreArray(x, &xx));
489  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
490 }
PetscFunctionBegin
const std::vector< double > x
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ populateVectorFromHandle()

template<class T >
PetscErrorCode SubChannel1PhaseProblem::populateVectorFromHandle ( Vec &  x,
const T solution,
const unsigned int  first_axial_level,
const unsigned int  last_axial_level,
const unsigned int  cross_dimension 
)
protectedinherited

Definition at line 445 of file SubChannel1PhaseProblem.h.

450 {
451  PetscScalar * xx;
452 
454  LibmeshPetscCall(VecGetArray(x, &xx));
455  for (unsigned int iz = first_axial_level; iz < last_axial_level + 1; iz++)
456  {
457  unsigned int iz_ind = iz - first_axial_level;
458  for (unsigned int i_l = 0; i_l < cross_dimension; i_l++)
459  {
460  auto * loc_node = _subchannel_mesh.getChannelNode(i_l, iz);
461  xx[iz_ind * cross_dimension + i_l] = loc_solution(loc_node);
462  }
463  }
464  LibmeshPetscCall(VecRestoreArray(x, &xx));
465 
466  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
467 }
PetscFunctionBegin
const std::vector< double > x
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ residualFunction()

libMesh::DenseVector< Real > SubChannel1PhaseProblem::residualFunction ( int  iblock,
libMesh::DenseVector< Real solution 
)
protectedinherited

Computes Residual Vector based on the lateral momentum conservation equation for block iblock & updates flow variables based on current crossflow solution.

Definition at line 1927 of file SubChannel1PhaseProblem.C.

Referenced by formFunction().

1928 {
1929  const unsigned int last_node = (iblock + 1) * _block_size;
1930  const unsigned int first_node = iblock * _block_size + 1;
1931  libMesh::DenseVector<Real> Wij_residual_vector(_n_gaps * _block_size, 0.0);
1932  // Assign the solution to the cross-flow matrix
1933  int i = 0;
1934  for (unsigned int iz = first_node; iz < last_node + 1; iz++)
1935  {
1936  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1937  {
1938  _Wij(i_gap, iz) = solution(i);
1939  i++;
1940  }
1941  }
1942 
1943  // Calculating sum of crossflows
1944  computeSumWij(iblock);
1945  // Solving axial flux
1946  computeMdot(iblock);
1947  // Calculation of turbulent Crossflow
1948  computeWijPrime(iblock);
1949  // Solving for Pressure Drop
1950  computeDP(iblock);
1951  // Solving for pressure
1952  computeP(iblock);
1953  // Populating lateral crossflow residual matrix
1954  computeWijResidual(iblock);
1955 
1956  // Turn the residual matrix into a residual vector
1957  for (unsigned int iz = 0; iz < _block_size; iz++)
1958  {
1959  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
1960  {
1961  int i = _n_gaps * iz + i_gap; // column wise transfer
1962  Wij_residual_vector(i) = _Wij_residual_matrix(i_gap, iz);
1963  }
1964  }
1965  return Wij_residual_vector;
1966 }
void computeSumWij(int iblock)
Computes net diversion crossflow per channel for block iblock.
void computeP(int iblock)
Computes Pressure per channel for block iblock.
void computeMdot(int iblock)
Computes mass flow per channel for block iblock.
void computeWijResidual(int iblock)
Computes Residual Matrix based on the lateral momentum conservation equation for block iblock...
libMesh::DenseMatrix< Real > _Wij_residual_matrix
libMesh::DenseMatrix< Real > & _Wij
void computeWijPrime(int iblock)
Computes turbulent crossflow per gap for block iblock.
void computeDP(int iblock)
Computes Pressure Drop per channel for block iblock.

◆ solveAndPopulateEnthalpy()

PetscErrorCode SubChannel1PhaseProblem::solveAndPopulateEnthalpy ( Mat  A,
Vec  rhs,
unsigned int  first_node,
unsigned int  last_node,
const char *  ksp_prefix 
)
protectedinherited

Solve a linear system (A * x = rhs) with a simple PCJACOBI KSP and populate the enthalpy solution into _h_soln for nodes [first_node, last_node].

Uses member tolerances (_rtol, _atol, _dtol, _maxit), mesh (_subchannel_mesh), channel count (_n_channels), and error/solution handles (mooseError, _h_soln).

Parameters
APETSc matrix (operators)
rhsPETSc vector (right-hand side)
first_nodeinclusive start axial node index
last_nodeinclusive end axial node index
ksp_prefixoptions prefix for KSP (e.g. "h_sys_"), may be nullptr

Definition at line 2020 of file SubChannel1PhaseProblem.C.

Referenced by QuadSubChannel1PhaseProblem::computeh(), and computeh().

2022 {
2024 
2025  // Create solution vector with rhs layout
2026  Vec x = nullptr;
2027  LibmeshPetscCall(VecDuplicate(rhs, &x));
2028 
2029  // KSP setup
2030  KSP ksp = nullptr;
2031  PC pc = nullptr;
2032  LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
2033  LibmeshPetscCall(KSPSetOperators(ksp, A, A));
2034  LibmeshPetscCall(KSPGetPC(ksp, &pc));
2035  LibmeshPetscCall(PCSetType(pc, PCJACOBI));
2036  LibmeshPetscCall(KSPSetTolerances(ksp, _rtol, _atol, _dtol, _maxit));
2037  if (ksp_prefix && *ksp_prefix)
2038  LibmeshPetscCall(KSPSetOptionsPrefix(ksp, ksp_prefix));
2039  LibmeshPetscCall(KSPSetFromOptions(ksp));
2040 
2041  // Solve
2042  LibmeshPetscCall(KSPSolve(ksp, rhs, x));
2043 
2044  // Scatter to _h_soln with sanity checks
2045  PetscScalar * xx = nullptr;
2046  LibmeshPetscCall(VecGetArray(x, &xx));
2047  for (unsigned int iz = first_node; iz <= last_node; ++iz)
2048  {
2049  const unsigned int iz_ind = iz - first_node;
2050  for (unsigned int i_ch = 0; i_ch < _n_channels; ++i_ch)
2051  {
2052  auto * node_out = _subchannel_mesh.getChannelNode(i_ch, iz);
2053  const PetscScalar h_out = xx[iz_ind * _n_channels + i_ch];
2054  if (h_out < 0.0)
2055  mooseError(
2056  name(), " : Calculation of negative Enthalpy h_out = ", h_out, " Axial Level = ", iz);
2057  _h_soln->set(node_out, h_out);
2058  }
2059  }
2060  LibmeshPetscCall(VecRestoreArray(x, &xx));
2061 
2062  // Cleanup
2063  LibmeshPetscCall(KSPDestroy(&ksp));
2064  LibmeshPetscCall(VecDestroy(&x));
2065 
2066  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
2067 }
std::unique_ptr< SolutionHandle > _h_soln
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
PetscFunctionBegin
const std::string & name() const
const std::vector< double > x
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
void mooseError(Args &&... args) const
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ solverSystemConverged()

bool SubChannel1PhaseProblem::solverSystemConverged ( const unsigned int  )
overridevirtualinherited

Reimplemented from ExternalProblem.

Definition at line 437 of file SubChannel1PhaseProblem.C.

438 {
439  return _converged;
440 }
bool _converged
Variable that informs whether we exited external solve with a converged solution or not...

◆ syncSolutions()

void SubChannel1PhaseProblem::syncSolutions ( Direction  direction)
overridevirtualinherited

Implements ExternalProblem.

Definition at line 2813 of file SubChannel1PhaseProblem.C.

2814 {
2815 }

◆ validParams()

InputParameters TriSubChannel1PhaseProblem::validParams ( )
static

Definition at line 23 of file TriSubChannel1PhaseProblem.C.

24 {
26  params.addClassDescription("Solver class for subchannels in a triangular lattice assembly and "
27  "bare/wire-wrapped fuel pins");
28  return params;
29 }
static InputParameters validParams()
void addClassDescription(const std::string &doc_string)

Member Data Documentation

◆ _added_K

PetscScalar SubChannel1PhaseProblem::_added_K = 0.0
protectedinherited

Added resistances for monolithic convergence.

Definition at line 408 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::implicitPetscSolve().

◆ _added_K_old

PetscScalar SubChannel1PhaseProblem::_added_K_old = 1000.0
protectedinherited

◆ _amc_advective_derivative_mat

Mat SubChannel1PhaseProblem::_amc_advective_derivative_mat
protectedinherited

Axial momentum conservation - advective (Eulerian) derivative.

Definition at line 356 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_advective_derivative_rhs

Vec SubChannel1PhaseProblem::_amc_advective_derivative_rhs
protectedinherited

◆ _amc_cross_derivative_mat

Mat SubChannel1PhaseProblem::_amc_cross_derivative_mat
protectedinherited

Axial momentum conservation - cross flux derivative.

Definition at line 359 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_cross_derivative_rhs

Vec SubChannel1PhaseProblem::_amc_cross_derivative_rhs
protectedinherited

◆ _amc_friction_force_mat

Mat SubChannel1PhaseProblem::_amc_friction_force_mat
protectedinherited

Axial momentum conservation - friction force.

Definition at line 362 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_friction_force_rhs

Vec SubChannel1PhaseProblem::_amc_friction_force_rhs
protectedinherited

◆ _amc_gravity_rhs

Vec SubChannel1PhaseProblem::_amc_gravity_rhs
protectedinherited

Axial momentum conservation - buoyancy force No implicit matrix.

Definition at line 366 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_pressure_force_mat

Mat SubChannel1PhaseProblem::_amc_pressure_force_mat
protectedinherited

◆ _amc_pressure_force_rhs

Vec SubChannel1PhaseProblem::_amc_pressure_force_rhs
protectedinherited

◆ _amc_sys_mdot_mat

Mat SubChannel1PhaseProblem::_amc_sys_mdot_mat
protectedinherited

◆ _amc_sys_mdot_rhs

Vec SubChannel1PhaseProblem::_amc_sys_mdot_rhs
protectedinherited

◆ _amc_time_derivative_mat

Mat SubChannel1PhaseProblem::_amc_time_derivative_mat
protectedinherited

Axial momentum conservation - time derivative.

Definition at line 353 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_time_derivative_rhs

Vec SubChannel1PhaseProblem::_amc_time_derivative_rhs
protectedinherited

◆ _amc_turbulent_cross_flows_mat

Mat SubChannel1PhaseProblem::_amc_turbulent_cross_flows_mat
protectedinherited

Mass conservation - density time derivative No implicit matrix.

Axial momentum Axial momentum conservation - compute turbulent cross fluxes

Definition at line 350 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeWijPrime(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _amc_turbulent_cross_flows_rhs

Vec SubChannel1PhaseProblem::_amc_turbulent_cross_flows_rhs
protectedinherited

◆ _atol

const PetscReal& SubChannel1PhaseProblem::_atol
protectedinherited

◆ _block_size

unsigned int SubChannel1PhaseProblem::_block_size
protectedinherited

◆ _cmc_advective_derivative_mat

Mat SubChannel1PhaseProblem::_cmc_advective_derivative_mat
protectedinherited

Cross momentum conservation - advective (Eulerian) derivative.

Definition at line 379 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeWijResidual(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _cmc_advective_derivative_rhs

Vec SubChannel1PhaseProblem::_cmc_advective_derivative_rhs
protectedinherited

◆ _cmc_friction_force_mat

Mat SubChannel1PhaseProblem::_cmc_friction_force_mat
protectedinherited

◆ _cmc_friction_force_rhs

Vec SubChannel1PhaseProblem::_cmc_friction_force_rhs
protectedinherited

◆ _cmc_pressure_force_mat

Mat SubChannel1PhaseProblem::_cmc_pressure_force_mat
protectedinherited

◆ _cmc_pressure_force_rhs

Vec SubChannel1PhaseProblem::_cmc_pressure_force_rhs
protectedinherited

◆ _cmc_sys_Wij_mat

Mat SubChannel1PhaseProblem::_cmc_sys_Wij_mat
protectedinherited

◆ _cmc_sys_Wij_rhs

Vec SubChannel1PhaseProblem::_cmc_sys_Wij_rhs
protectedinherited

◆ _cmc_time_derivative_mat

Mat SubChannel1PhaseProblem::_cmc_time_derivative_mat
protectedinherited

Cross momentum Cross momentum conservation - time derivative.

Definition at line 376 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeWijResidual(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _cmc_time_derivative_rhs

Vec SubChannel1PhaseProblem::_cmc_time_derivative_rhs
protectedinherited

◆ _compute_density

const bool SubChannel1PhaseProblem::_compute_density
protectedinherited

Flag that activates or deactivates the calculation of density.

Definition at line 214 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _compute_power

const bool SubChannel1PhaseProblem::_compute_power
protectedinherited

Flag that informs if we need to solve the Enthalpy/Temperature equations or not.

Definition at line 218 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _compute_viscosity

const bool SubChannel1PhaseProblem::_compute_viscosity
protectedinherited

Flag that activates or deactivates the calculation of viscosity.

Definition at line 216 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _converged

bool SubChannel1PhaseProblem::_converged
protectedinherited

Variable that informs whether we exited external solve with a converged solution or not.

Definition at line 224 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve(), SubChannel1PhaseProblem::solverSystemConverged(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _correction_factor

PetscScalar SubChannel1PhaseProblem::_correction_factor = 1.0
protectedinherited

◆ _CT

Real SubChannel1PhaseProblem::_CT
protectedinherited

Turbulent modeling parameter used in axial momentum equation.

Definition at line 230 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeDP(), and SubChannel1PhaseProblem::initialSetup().

◆ _deformation

bool SubChannel1PhaseProblem::_deformation = false
protectedinherited

Flag that activates the effect of deformation (pin/duct) based on the auxvalues for displacement, Dpin.

Definition at line 259 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::detectDeformation(), QuadSubChannel1PhaseProblem::initializeSolution(), and initializeSolution().

◆ _dir_grav

const Real SubChannel1PhaseProblem::_dir_grav
protectedinherited

Definition at line 249 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeDP().

◆ _displacement_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_displacement_soln
protectedinherited

◆ _DP

libMesh::DenseMatrix<Real> SubChannel1PhaseProblem::_DP
protectedinherited

◆ _DP_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_DP_soln
protectedinherited

◆ _Dpin_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_Dpin_soln
protectedinherited

◆ _dt

Real SubChannel1PhaseProblem::_dt
protectedinherited

◆ _dtol

const PetscReal& SubChannel1PhaseProblem::_dtol
protectedinherited

◆ _duct_heat_flux_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_duct_heat_flux_soln
protectedinherited

Definition at line 282 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::initialSetup().

◆ _duct_HTC_closure

const SCMHTCClosureBase* SubChannel1PhaseProblem::_duct_HTC_closure
protectedinherited

◆ _duct_mesh_exist

const bool SubChannel1PhaseProblem::_duct_mesh_exist
protectedinherited

◆ _ff_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_ff_soln
protectedinherited

◆ _fp

const SinglePhaseFluidProperties* SubChannel1PhaseProblem::_fp
inherited

◆ _friction_args

struct SubChannel1PhaseProblem::FrictionStruct SubChannel1PhaseProblem::_friction_args
inherited

◆ _friction_closure

const SCMFrictionClosureBase* SubChannel1PhaseProblem::_friction_closure
protectedinherited

◆ _g_grav

const Real SubChannel1PhaseProblem::_g_grav
protectedinherited

Definition at line 201 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeDP().

◆ _gravity_direction

const MooseEnum SubChannel1PhaseProblem::_gravity_direction
protectedinherited

The direction of gravity.

Definition at line 248 of file SubChannel1PhaseProblem.h.

◆ _h_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_h_soln
protectedinherited

◆ _hc_added_heat_rhs

Vec SubChannel1PhaseProblem::_hc_added_heat_rhs
protectedinherited

◆ _hc_advective_derivative_mat

Mat SubChannel1PhaseProblem::_hc_advective_derivative_mat
protectedinherited

Enthalpy conservation - advective (Eulerian) derivative;.

Definition at line 396 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), QuadSubChannel1PhaseProblem::computeh(), computeh(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _hc_advective_derivative_rhs

Vec SubChannel1PhaseProblem::_hc_advective_derivative_rhs
protectedinherited

◆ _hc_axial_heat_conduction_mat

Mat TriSubChannel1PhaseProblem::_hc_axial_heat_conduction_mat
protected

Definition at line 34 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_axial_heat_conduction_rhs

Vec TriSubChannel1PhaseProblem::_hc_axial_heat_conduction_rhs
protected

Definition at line 35 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_cross_derivative_mat

Mat SubChannel1PhaseProblem::_hc_cross_derivative_mat
protectedinherited

◆ _hc_cross_derivative_rhs

Vec SubChannel1PhaseProblem::_hc_cross_derivative_rhs
protectedinherited

◆ _hc_radial_heat_conduction_mat

Mat TriSubChannel1PhaseProblem::_hc_radial_heat_conduction_mat
protected

Definition at line 36 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_radial_heat_conduction_rhs

Vec TriSubChannel1PhaseProblem::_hc_radial_heat_conduction_rhs
protected

Definition at line 37 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_sweep_enthalpy_mat

Mat TriSubChannel1PhaseProblem::_hc_sweep_enthalpy_mat
protected

Definition at line 38 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_sweep_enthalpy_rhs

Vec TriSubChannel1PhaseProblem::_hc_sweep_enthalpy_rhs
protected

Definition at line 39 of file TriSubChannel1PhaseProblem.h.

Referenced by cleanUp(), computeh(), and TriSubChannel1PhaseProblem().

◆ _hc_sys_h_mat

Mat SubChannel1PhaseProblem::_hc_sys_h_mat
protectedinherited

◆ _hc_sys_h_rhs

Vec SubChannel1PhaseProblem::_hc_sys_h_rhs
protectedinherited

◆ _hc_time_derivative_mat

Mat SubChannel1PhaseProblem::_hc_time_derivative_mat
protectedinherited

◆ _hc_time_derivative_rhs

Vec SubChannel1PhaseProblem::_hc_time_derivative_rhs
protectedinherited

◆ _HTC_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_HTC_soln
protectedinherited

◆ _implicit_bool

const bool SubChannel1PhaseProblem::_implicit_bool
protectedinherited

◆ _interpolation_scheme

const MooseEnum SubChannel1PhaseProblem::_interpolation_scheme
protectedinherited

The interpolation method used in constructing the systems.

Definition at line 246 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeDP(), computeh(), and SubChannel1PhaseProblem::computeInterpolationCoefficients().

◆ _kij

const Real& SubChannel1PhaseProblem::_kij
protectedinherited

◆ _max_sumWij

PetscScalar SubChannel1PhaseProblem::_max_sumWij
protectedinherited

◆ _max_sumWij_new

PetscScalar SubChannel1PhaseProblem::_max_sumWij_new
protectedinherited

◆ _maxit

const PetscInt& SubChannel1PhaseProblem::_maxit
protectedinherited

◆ _mc_axial_convection_mat

Mat SubChannel1PhaseProblem::_mc_axial_convection_mat
protectedinherited

◆ _mc_axial_convection_rhs

Vec SubChannel1PhaseProblem::_mc_axial_convection_rhs
protectedinherited

◆ _mc_sumWij_mat

Mat SubChannel1PhaseProblem::_mc_sumWij_mat
protectedinherited

Matrices and vectors to be used in implicit assembly Mass conservation Mass conservation - sum of cross fluxes.

Definition at line 338 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::cleanUp(), SubChannel1PhaseProblem::computeSumWij(), SubChannel1PhaseProblem::implicitPetscSolve(), and SubChannel1PhaseProblem::SubChannel1PhaseProblem().

◆ _mdot_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_mdot_soln
protectedinherited

◆ _mixing_closure

const SCMMixingClosureBase* SubChannel1PhaseProblem::_mixing_closure
protectedinherited

◆ _mu_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_mu_soln
protectedinherited

◆ _n_blocks

unsigned int SubChannel1PhaseProblem::_n_blocks
protectedinherited

◆ _n_cells

unsigned int SubChannel1PhaseProblem::_n_cells
protectedinherited

◆ _n_channels

unsigned int SubChannel1PhaseProblem::_n_channels
protectedinherited

◆ _n_gaps

unsigned int SubChannel1PhaseProblem::_n_gaps
protectedinherited

◆ _n_pins

unsigned int SubChannel1PhaseProblem::_n_pins
protectedinherited

◆ _nusselt_args

struct SubChannel1PhaseProblem::NusseltStruct SubChannel1PhaseProblem::_nusselt_args
inherited

◆ _one

Real SubChannel1PhaseProblem::_one
protectedinherited

Definition at line 210 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _P_out

const PostprocessorValue& SubChannel1PhaseProblem::_P_out
inherited

◆ _P_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_P_soln
protectedinherited

◆ _P_tol

const Real& SubChannel1PhaseProblem::_P_tol
protectedinherited

Convergence tolerance for the pressure loop in external solve.

Definition at line 232 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _pin_HTC_closure

const SCMHTCClosureBase* SubChannel1PhaseProblem::_pin_HTC_closure
protectedinherited

◆ _pin_mesh_exist

const bool SubChannel1PhaseProblem::_pin_mesh_exist
protectedinherited

◆ _prod

Vec SubChannel1PhaseProblem::_prod
protectedinherited

◆ _prodp

Vec SubChannel1PhaseProblem::_prodp
protectedinherited

◆ _q_prime_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_q_prime_soln
protectedinherited

Definition at line 281 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::initialSetup().

◆ _rho_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_rho_soln
protectedinherited

◆ _rtol

const PetscReal& SubChannel1PhaseProblem::_rtol
protectedinherited

◆ _S_flow_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_S_flow_soln
protectedinherited

◆ _segregated_bool

const bool SubChannel1PhaseProblem::_segregated_bool
protectedinherited

◆ _staggered_pressure_bool

const bool SubChannel1PhaseProblem::_staggered_pressure_bool
protectedinherited

Flag to define the usage of staggered or collocated pressure.

Definition at line 253 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeP(), and SubChannel1PhaseProblem::computeWijResidual().

◆ _subchannel_mesh

SubChannelMesh& SubChannel1PhaseProblem::_subchannel_mesh
protectedinherited

◆ _SumWij_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_SumWij_soln
protectedinherited

◆ _T_maxit

const int& SubChannel1PhaseProblem::_T_maxit
protectedinherited

Maximum iterations for the inner temperature loop.

Definition at line 236 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _T_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_T_soln
protectedinherited

◆ _T_tol

const Real& SubChannel1PhaseProblem::_T_tol
protectedinherited

Convergence tolerance for the temperature loop in internal solve.

Definition at line 234 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _Tduct_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_Tduct_soln
protectedinherited

◆ _time_integrator_checked

bool SubChannel1PhaseProblem::_time_integrator_checked = false
protectedinherited

Whether the time integrator has been checked for consistency with the implementation.

Definition at line 226 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::externalSolve().

◆ _Tpin_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_Tpin_soln
protectedinherited

◆ _TR

Real SubChannel1PhaseProblem::_TR
protectedinherited

Flag that activates or deactivates the transient parts of the equations we solve by multiplication.

Definition at line 212 of file SubChannel1PhaseProblem.h.

Referenced by SubChannel1PhaseProblem::computeDP(), QuadSubChannel1PhaseProblem::computeh(), computeh(), SubChannel1PhaseProblem::computeMdot(), SubChannel1PhaseProblem::computeWijResidual(), and SubChannel1PhaseProblem::externalSolve().

◆ _tri_sch_mesh

TriSubChannelMesh& TriSubChannel1PhaseProblem::_tri_sch_mesh
protected

◆ _verbose_subchannel

const bool SubChannel1PhaseProblem::_verbose_subchannel
protectedinherited

◆ _w_perim_soln

std::unique_ptr<SolutionHandle> SubChannel1PhaseProblem::_w_perim_soln
protectedinherited

◆ _Wij

libMesh::DenseMatrix<Real>& SubChannel1PhaseProblem::_Wij
protectedinherited

◆ _Wij_old

libMesh::DenseMatrix<Real> SubChannel1PhaseProblem::_Wij_old
protectedinherited

◆ _Wij_residual_matrix

libMesh::DenseMatrix<Real> SubChannel1PhaseProblem::_Wij_residual_matrix
protectedinherited

◆ _Wij_vec

Vec SubChannel1PhaseProblem::_Wij_vec
protectedinherited

◆ _WijPrime

libMesh::DenseMatrix<Real> SubChannel1PhaseProblem::_WijPrime
protectedinherited

◆ _z_grid

std::vector<Real> SubChannel1PhaseProblem::_z_grid
protectedinherited

The documentation for this class was generated from the following files: