Skip to content

Commit

Permalink
Merge pull request idaholab#20993 from joshuahansel/hs-coupling
Browse files Browse the repository at this point in the history
Added component to couple 2D heat structures
  • Loading branch information
joshuahansel committed May 16, 2022
2 parents 2e113d4 + 54e280a commit dc704a7
Show file tree
Hide file tree
Showing 19 changed files with 1,004 additions and 21 deletions.
3 changes: 2 additions & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -39,7 +39,7 @@
/modules/doc/content/newsletter @cticenhour
/modules/electromagnetics @cticenhour
/modules/external_petsc_solver @fdkong
/modules/fluid_properties @andrsd
/modules/fluid_properties @joshuahansel
/modules/fsi @fdkong
/modules/functional_expansion_tools @lindsayad
/modules/navier_stokes @lindsayad @GiudGiud
Expand All @@ -48,6 +48,7 @@
/modules/rdg @joshuahansel
/modules/stochastic_tools @zachmprince
/modules/tensor_mechanics @bwspenc @dschwen @jiangwen84
/modules/thermal_hydraulics @joshuahansel
/modules/xfem @bwspenc @jiangwen84

/scripts/hpc_proxy.pac @loganharbour
Expand Down
5 changes: 5 additions & 0 deletions modules/doc/content/newsletter/2022_05.md
Expand Up @@ -7,6 +7,11 @@ for a complete description of all MOOSE changes.

## MOOSE Improvements

- The component [HeatStructure2DCoupler.md] was added to the
[Thermal hydraulics module](modules/thermal_hydraulics/index.md), which allows
2D heat structures to be coupled via a heat heat transfer coefficient between
two coincident boundaries.

## libMesh-level Changes

### `2022.05.06` Update
Expand Down
@@ -0,0 +1 @@
!template load file=stubs/moose_object.md.template name=HeatStructure2DCouplerBC syntax=/BCs/HeatStructure2DCouplerBC
@@ -0,0 +1 @@
!template load file=stubs/moose_object.md.template name=HeatStructure2DCouplerRZBC syntax=/BCs/HeatStructure2DCouplerRZBC
@@ -0,0 +1,39 @@
# HeatStructure2DCoupler

This component couples two [2D heat structures](component_groups/heat_structure_2d.md)
via a heat transfer coefficient.

## Usage

This component has the following restrictions:

- The coupled heat structures must be [2D heat structures](component_groups/heat_structure_2d.md).
- The coupled heat structures must be of the same type.
- Only one boundary name may be provided in each of the
[!param](/Components/HeatStructure2DCoupler/primary_boundary) and
[!param](/Components/HeatStructure2DCoupler/secondary_boundary) parameters.
- The meshes along the coupled boundaries must be coincident, i.e., each node
on each side must be at an identical location as a node on the other side.

!syntax parameters /Components/HeatStructure2DCoupler

## Formulation

!include heat_structure_formulation.md

!include heat_structure_boundary_formulation_neumann.md

For the heat structure $k$, the incoming boundary heat flux $q_b$ is computed as

\begin{equation}
q_b = \mathcal{H} (T_j - T_k) \eqc
\end{equation}
where

- $\mathcal{H}$ is the heat transfer coefficient,
- $T_k$ is the surface temperature of the heat structure $k$, and
- $T_j$ is the surface temperature of the coupled heat structure $j$.

!syntax inputs /Components/HeatStructure2DCoupler

!syntax children /Components/HeatStructure2DCoupler
41 changes: 41 additions & 0 deletions modules/thermal_hydraulics/include/bcs/HeatStructure2DCouplerBC.h
@@ -0,0 +1,41 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "ADIntegratedBC.h"

class MeshAlignment2D2D;

/**
* Applies BC for HeatStructure2DCoupler for plate heat structure
*/
class HeatStructure2DCouplerBC : public ADIntegratedBC
{
public:
HeatStructure2DCouplerBC(const InputParameters & parameters);

virtual ADReal computeQpResidual() override;

protected:
/// Heat transfer coefficient
const Function & _htc;
/// Variable number of the variable to transfer
const unsigned int _coupled_variable_number;
/// Mesh alignment object
const MeshAlignment2D2D & _mesh_alignment;

/// Nonlinear system
const SystemBase & _nl_sys;
/// Solution vector
const NumericVector<Number> * const & _serialized_solution;

public:
static InputParameters validParams();
};
@@ -0,0 +1,28 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "HeatStructure2DCouplerBC.h"
#include "RZSymmetry.h"

/**
* Applies BC for HeatStructure2DCoupler for cylindrical heat structure
*/
class HeatStructure2DCouplerRZBC : public HeatStructure2DCouplerBC, public RZSymmetry
{
public:
HeatStructure2DCouplerRZBC(const InputParameters & parameters);

protected:
virtual ADReal computeQpResidual() override;

public:
static InputParameters validParams();
};
@@ -0,0 +1,43 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "BoundaryBase.h"
#include "MeshAlignment2D2D.h"

/**
* Couples boundaries of two 2D heat structures via a heat transfer coefficient
*/
class HeatStructure2DCoupler : public BoundaryBase
{
public:
HeatStructure2DCoupler(const InputParameters & parameters);

virtual void addMooseObjects() override;

protected:
virtual void init() override;
virtual void check() const override;

/// Primary and secondary heat structure names
const std::vector<std::string> _hs_names;
/// Primary and secondary heat structure boundaries
const std::vector<BoundaryName> _hs_boundaries;

/// Mesh alignment
MeshAlignment2D2D _mesh_alignment;
/// Flag for each heat structure being HeatStructurePlate
std::vector<bool> _is_plate;
/// Flag for each heat structure deriving from HeatStructureCylindricalBase
std::vector<bool> _is_cylindrical;

public:
static InputParameters validParams();
};
27 changes: 19 additions & 8 deletions modules/thermal_hydraulics/include/components/HeatStructureBase.h
Expand Up @@ -79,6 +79,22 @@ class HeatStructureBase : public GeometricalComponent
*/
Real getNumberOfUnits() const { return _num_rods; }

/**
* Return true if this heat structure has the supplied boundary
*/
bool hasBoundary(const BoundaryName & boundary_name) const;

/**
* Get boundary info associated with the heat structure boundary
*
* @param[in] boundary Boundary name of a heat structure boundary
*
* @return The list of tuples (element id, local side id) that is associated with boundary
* `boundary`
*/
const std::vector<std::tuple<dof_id_type, unsigned short int>> &
getBoundaryInfo(const BoundaryName & boundary_name) const;

/**
* Get boundary info associated with the heat structure side
*
Expand Down Expand Up @@ -180,14 +196,9 @@ class HeatStructureBase : public GeometricalComponent
std::vector<unsigned int> _outer_heat_node_ids;
/// Nodes at the inner side of the generated heat structure
std::vector<unsigned int> _inner_heat_node_ids;
/// Boundary info for the outer side of the heat structure
std::vector<std::tuple<dof_id_type, unsigned short int>> _outer_bnd_info;
/// Boundary info for the inner side of the heat structure
std::vector<std::tuple<dof_id_type, unsigned short int>> _inner_bnd_info;
/// Boundary info for the start side of the heat structure
std::vector<std::tuple<dof_id_type, unsigned short int>> _start_bnd_info;
/// Boundary info for the end side of the heat structure
std::vector<std::tuple<dof_id_type, unsigned short int>> _end_bnd_info;
/// Map of boundary name to list of tuples of element and side IDs for that boundary
std::map<BoundaryName, std::vector<std::tuple<dof_id_type, unsigned short int>>>
_hs_boundary_info;

/// True if this heat structure is connected to at least one flow channel
mutable bool _connected_to_flow_channel;
Expand Down
82 changes: 82 additions & 0 deletions modules/thermal_hydraulics/include/utils/MeshAlignment2D2D.h
@@ -0,0 +1,82 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/primary/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#pragma once

#include "MooseMesh.h"

class MooseMesh;

/**
* Builds mapping between two aligned 2D boundaries
*/
class MeshAlignment2D2D
{
public:
/**
* Constructor
*
* @param subproblem[in] Subproblem
*/
MeshAlignment2D2D(const MooseMesh & mesh);

/**
* Builds the neighborhood information between primary and secondary side
*
* @param primary_boundary_info[in] List of tuples (elem_id, side_id) of the primary side
* @param secondary_boundary_info[in] List of tuples (elem_id, side_id) of the secondary side
*/
void initialize(
const std::vector<std::tuple<dof_id_type, unsigned short int>> & primary_boundary_info,
const std::vector<std::tuple<dof_id_type, unsigned short int>> & secondary_boundary_info);

/**
* Returns true if the primary and secondary boundaries are coincident
*/
bool meshesAreCoincident() const { return _all_points_are_coincident; }

/**
* Returns the list of element IDs on the primary boundary
*/
const std::vector<dof_id_type> & getPrimaryBoundaryElemIDs() const { return _primary_elem_ids; }

/**
* Gets the neighbor element ID for a given element ID
*
* @param[in] elem_id Element ID for which to find the neighbor element ID
*/
dof_id_type getNeighborElemID(const dof_id_type & elem_id) const;

/**
* Returns true if the given node ID has a neighboring node
*
* @param[in] node_id Node ID for which to find the neighbor node ID
*/
bool hasNeighborNode(const dof_id_type & node_id) const;

/**
* Gets the neighbor node ID for a given node ID
*
* @param[in] node_id Node ID for which to find the neighbor node ID
*/
dof_id_type getNeighborNodeID(const dof_id_type & node_id) const;

protected:
/// Mesh
const MooseMesh & _mesh;

/// List of primary element IDs
std::vector<dof_id_type> _primary_elem_ids;
/// Map of element ID to neighboring element ID
std::map<dof_id_type, dof_id_type> _elem_id_map;
/// Map of node ID to neighboring node ID
std::map<dof_id_type, dof_id_type> _node_id_map;
/// Flag that all quadrature points are coincident between boundaries
bool _all_points_are_coincident;
};
68 changes: 68 additions & 0 deletions modules/thermal_hydraulics/src/bcs/HeatStructure2DCouplerBC.C
@@ -0,0 +1,68 @@
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "HeatStructure2DCouplerBC.h"
#include "MeshAlignment2D2D.h"
#include "Function.h"

registerMooseObject("ThermalHydraulicsApp", HeatStructure2DCouplerBC);

InputParameters
HeatStructure2DCouplerBC::validParams()
{
InputParameters params = ADIntegratedBC::validParams();

params.addRequiredParam<FunctionName>("heat_transfer_coefficient",
"Heat transfer coefficient function");
params.addRequiredParam<std::string>("coupled_variable",
"The variable on the coupled heat structure boundary");
params.addRequiredParam<MeshAlignment2D2D *>("_mesh_alignment", "Mesh alignment object");

params.addClassDescription("Applies BC for HeatStructure2DCoupler for plate heat structure");

return params;
}

HeatStructure2DCouplerBC::HeatStructure2DCouplerBC(const InputParameters & parameters)
: ADIntegratedBC(parameters),

_htc(getFunction("heat_transfer_coefficient")),
_coupled_variable_number(
_subproblem
.getVariable(_tid, getParam<std::string>("coupled_variable"), Moose::VAR_NONLINEAR)
.number()),
_mesh_alignment(*getParam<MeshAlignment2D2D *>("_mesh_alignment")),

_nl_sys(_subproblem.systemBaseNonlinear()),
_serialized_solution(_nl_sys.currentSolution())
{
}

ADReal
HeatStructure2DCouplerBC::computeQpResidual()
{
// Compute temperature of neighboring side
ADReal T_coupled_hs = 0;
for (const auto j : _current_elem->node_index_range())
{
const auto node_id = (_current_elem->node_ref(j)).id();
if (_mesh_alignment.hasNeighborNode(node_id))
{
const auto neighbor_node_id = _mesh_alignment.getNeighborNodeID(node_id);
const Node & neighbor_node = _mesh.nodeRef(neighbor_node_id);
const auto dof_number =
neighbor_node.dof_number(_nl_sys.number(), _coupled_variable_number, 0);
ADReal T_node = (*_serialized_solution)(dof_number);
Moose::derivInsert(T_node.derivatives(), dof_number, 1.0);
T_coupled_hs += T_node * _test[j][_qp];
}
}

return _htc.value(_t, _q_point[_qp]) * (_u[_qp] - T_coupled_hs) * _test[_i][_qp];
}

0 comments on commit dc704a7

Please sign in to comment.