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

Mesh generator that builds a mesh of 1D lines representing subchannels and pins in a triangular assembly. More...

#include <SCMTriAssemblyMeshGenerator.h>

Inheritance diagram for SCMTriAssemblyMeshGenerator:
[legend]

Public Types

typedef DataFileName DataFileParameterType
 

Public Member Functions

 SCMTriAssemblyMeshGenerator (const InputParameters &parameters)
 
std::unique_ptr< MeshBase > generate () override
 
std::unique_ptr< CSG::CSGBasegenerateInternalCSG ()
 
std::unique_ptr< MeshBase > generateInternal ()
 
const std::set< MeshGeneratorName > & getRequestedMeshGenerators () const
 
const std::set< MeshGeneratorName > & getRequestedMeshGeneratorsForSub () const
 
void addParentMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
void addChildMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
const std::set< const MeshGenerator *, Comparator > & getParentMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getChildMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getSubMeshGenerators () const
 
bool isParentMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isChildMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isNullMeshName (const MeshGeneratorName &name) const
 
bool hasSaveMesh () const
 
bool hasOutput () const
 
const std::string & getSavedMeshName () const
 
bool hasGenerateData () const
 
bool hasGenerateCSG () const
 
bool isDataOnly () 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
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Static Public Member Functions

static InputParameters validParams ()
 
static bool hasGenerateData (const InputParameters &params)
 
static bool hasGenerateCSG (const InputParameters &params)
 
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 setHasGenerateData (InputParameters &params)
 
static void setHasGenerateCSG (InputParameters &params)
 

Public Attributes

 usingCombinedWarningSolutionWarnings
 
const ConsoleStream _console
 

Static Public Attributes

static const std::string data_only_param
 
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
 
static constexpr auto SYSTEM
 
static constexpr auto NAME
 

Protected Member Functions

void buildPinMesh (MeshBase &mesh_base)
 Build the 1D pin elements and append them to the subchannel mesh. More...
 
virtual void generateData ()
 
virtual std::unique_ptr< CSG::CSGBasegenerateCSG ()
 
TcopyMeshProperty (const std::string &target_data_name, const std::string &source_data_name, const std::string &source_mesh)
 
TcopyMeshProperty (const std::string &source_data_name, const std::string &source_mesh)
 
std::unique_ptr< MeshBase > & getMesh (const std::string &param_name, const bool allow_invalid=false)
 
std::vector< std::unique_ptr< MeshBase > *> getMeshes (const std::string &param_name)
 
std::unique_ptr< MeshBase > & getMeshByName (const MeshGeneratorName &mesh_generator_name)
 
std::vector< std::unique_ptr< MeshBase > *> getMeshesByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
std::unique_ptr< CSG::CSGBase > & getCSGBase (const std::string &param_name)
 
std::unique_ptr< CSG::CSGBase > & getCSGBaseByName (const MeshGeneratorName &mesh_generator_name)
 
std::vector< std::unique_ptr< CSG::CSGBase > *> getCSGBases (const std::string &param_name)
 
std::vector< std::unique_ptr< CSG::CSGBase > *> getCSGBasesByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
void declareMeshForSub (const std::string &param_name)
 
void declareMeshesForSub (const std::string &param_name)
 
void declareMeshForSubByName (const MeshGeneratorName &mesh_generator_name)
 
void declareMeshesForSubByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
std::unique_ptr< MeshBase > buildMeshBaseObject (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< DistributedMesh > buildDistributedMesh (unsigned int dim=libMesh::invalid_uint)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, Ts... extra_input_parameters)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, InputParameters params)
 
void declareNullMeshName (const MeshGeneratorName &name)
 
void flagInvalidSolutionInternal (const InvalidSolutionID invalid_solution_id) const
 
InvalidSolutionID registerInvalidSolutionInternal (const std::string &message, const bool warning) const
 
const TgetMeshProperty (const std::string &data_name, const std::string &prefix)
 
const TgetMeshProperty (const std::string &data_name)
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name) const
 
bool hasMeshProperty (const std::string &data_name) const
 
std::string meshPropertyName (const std::string &data_name) const
 
TdeclareMeshProperty (const std::string &data_name, Args &&... args)
 
TdeclareMeshProperty (const std::string &data_name, const T &data_value)
 
TdeclareMeshProperty (const std::string &data_name, Args &&... args)
 
TdeclareMeshProperty (const std::string &data_name, const T &data_value)
 
TsetMeshProperty (const std::string &data_name, Args &&... args)
 
TsetMeshProperty (const std::string &data_name, const T &data_value)
 
TsetMeshProperty (const std::string &data_name, Args &&... args)
 
TsetMeshProperty (const std::string &data_name, const T &data_value)
 

Static Protected Member Functions

static std::string meshPropertyName (const std::string &data_name, const std::string &prefix)
 

Protected Attributes

const Real _unheated_length_entry
 unheated length of the fuel Pin at the entry of the assembly More...
 
const Real _heated_length
 heated length of the fuel Pin More...
 
const Real _unheated_length_exit
 unheated length of the fuel Pin at the exit of the assembly More...
 
const unsigned int _subchannel_block_id
 subchannel block index More...
 
const unsigned int _pin_block_id
 pin block index More...
 
std::vector< Real_z_grid
 axial location of nodes More...
 
std::vector< std::vector< Real > > _k_grid
 axial form loss coefficient per computational cell More...
 
const std::vector< Real > & _spacer_z
 axial location of the spacers More...
 
const std::vector< Real > & _spacer_k
 form loss coefficient of the spacers More...
 
const std::vector< Real_z_blockage
 axial location of blockage (inlet, outlet) [m] More...
 
const std::vector< unsigned int_index_blockage
 index of subchannels affected by blockage More...
 
const std::vector< Real_reduction_blockage
 area reduction of subchannels affected by blockage More...
 
const std::vector< Real_k_blockage
 form loss coefficient of subchannels affected by blockage More...
 
const Real _pitch
 Distance between the neighbor fuel pins, pitch. More...
 
const Real_kij
 Lateral form loss coefficient. More...
 
const Real _pin_diameter
 fuel Pin diameter More...
 
const unsigned int _n_cells
 number of axial cells More...
 
const unsigned int _n_rings
 number of rings of fuel pins More...
 
unsigned int _n_channels
 number of subchannels More...
 
const Real _flat_to_flat
 the distance between flat surfaces of the duct facing each other More...
 
const Real _dwire
 wire diameter More...
 
const Real _hwire
 wire lead length More...
 
const Real _duct_to_pin_gap
 the gap thickness between the duct and peripheral fuel pins More...
 
std::vector< std::vector< Node * > > _nodes
 nodes More...
 
std::vector< std::vector< Node * > > _pin_nodes
 pin nodes More...
 
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
 stores the channel pairs for each gap More...
 
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
 stores the fuel pin pairs for each gap each gap More...
 
std::vector< std::vector< unsigned int > > _chan_to_gap_map
 stores the gaps that forms each subchannel More...
 
std::vector< std::vector< Real > > _sign_id_crossflow_map
 Defines the global cross-flow direction -1 or 1 for each subchannel and for all gaps that are belonging to the corresponding subchannel. More...
 
std::vector< std::vector< Real > > _gij_map
 gap size More...
 
std::vector< std::vector< Real > > _subchannel_position
 x,y coordinates of the subchannel centroids More...
 
std::vector< Point > _pin_position
 x,y coordinates of the fuel pins More...
 
std::vector< std::vector< Real > > _pins_in_rings
 fuel pins that are belonging to each ring More...
 
std::vector< std::vector< unsigned int > > _chan_to_pin_map
 stores the fuel pins belonging to each subchannel More...
 
std::vector< std::vector< unsigned int > > _pin_to_chan_map
 stores the map from pins to channels More...
 
unsigned int _npins
 number of fuel pins More...
 
unsigned int _n_gaps
 number of gaps More...
 
std::vector< EChannelType_subch_type
 subchannel type More...
 
std::vector< EChannelType_gap_type
 gap type More...
 
std::vector< std::pair< unsigned int, unsigned int > > _gap_pairs_sf
 sweeping flow model gap pairs per channel to specify directional edge flow More...
 
std::vector< std::pair< unsigned int, unsigned int > > _chan_pairs_sf
 sweeping flow model channel pairs to specify directional edge flow More...
 
MooseMesh *const _mesh
 
const bool & _enabled
 
MooseApp_app
 
Factory_factory
 
ActionFactory_action_factory
 
const std::string & _type
 
const std::string & _name
 
const InputParameters_pars
 
const Parallel::Communicator & _communicator
 

Detailed Description

Mesh generator that builds a mesh of 1D lines representing subchannels and pins in a triangular assembly.

Definition at line 19 of file SCMTriAssemblyMeshGenerator.h.

Constructor & Destructor Documentation

◆ SCMTriAssemblyMeshGenerator()

SCMTriAssemblyMeshGenerator::SCMTriAssemblyMeshGenerator ( const InputParameters parameters)

initial assignment

Build channel-gap connectivity from the channel-pin and gap-pin maps.

Center channels are bounded by three center gaps connecting their three pin pairs. Edge channels are bounded by one center gap between their two pins and two perimeter gaps along the duct. Corner channels are bounded by the two perimeter gaps that meet at the corner pin.

For a two-ring assembly every outer-ring pin is a corner pin. Consequently an edge channel can find a corner channel at both of its endpoint pins. The edge still owns only three local gap entries, matching _sign_id_crossflow_map and the reverse _gap_to_chan_map construction below, so the second corner lookup is skipped once those three entries are already present.

Definition at line 78 of file SCMTriAssemblyMeshGenerator.C.

79  : MeshGenerator(params),
80  _unheated_length_entry(getParam<Real>("unheated_length_entry")),
81  _heated_length(getParam<Real>("heated_length")),
82  _unheated_length_exit(getParam<Real>("unheated_length_exit")),
83  _subchannel_block_id(getParam<unsigned int>("subchannel_block_id")),
84  _pin_block_id(getParam<unsigned int>("pin_block_id")),
85  _spacer_z(getParam<std::vector<Real>>("spacer_z")),
86  _spacer_k(getParam<std::vector<Real>>("spacer_k")),
87  _z_blockage(getParam<std::vector<Real>>("z_blockage")),
88  _index_blockage(getParam<std::vector<unsigned int>>("index_blockage")),
89  _reduction_blockage(getParam<std::vector<Real>>("reduction_blockage")),
90  _k_blockage(getParam<std::vector<Real>>("k_blockage")),
91  _pitch(getParam<Real>("pitch")),
92  _kij(getParam<Real>("Kij")),
93  _pin_diameter(getParam<Real>("pin_diameter")),
94  _n_cells(getParam<unsigned int>("n_cells")),
95  _n_rings(getParam<unsigned int>("nrings")),
96  _n_channels(0),
97  _flat_to_flat(getParam<Real>("flat_to_flat")),
98  _dwire(getParam<Real>("dwire")),
99  _hwire(getParam<Real>("hwire")),
100  _duct_to_pin_gap(0.5 *
101  (_flat_to_flat - (_n_rings - 1) * _pitch * std::sqrt(3.0) - _pin_diameter)),
102  _npins(0),
103  _n_gaps(0)
104 {
106 
107  if (_n_rings < 2)
108  paramError("nrings",
109  "'nrings' must be at least 2. In this mesh generator, the center pin counts as "
110  "the first ring, so a 7-pin bundle uses nrings = 2.");
111 
112  if (_n_cells == 0)
113  paramError("n_cells", "The number of axial cells must be greater than zero");
114 
115  if (total_length <= 0.0)
116  mooseError("Total bundle length must be greater than zero");
117 
118  if (_spacer_z.size() != _spacer_k.size())
119  mooseError("Size of vector spacer_z should be equal to size of vector spacer_k");
120 
121  for (const auto spacer_z : _spacer_z)
122  if (spacer_z < 0.0 || spacer_z > total_length)
123  paramError("spacer_z", "Location of spacers should be between zero and total bundle length");
124 
125  if (_z_blockage.size() != 2)
126  paramError("z_blockage", "Size of vector z_blockage must be 2");
127 
128  if (_z_blockage.front() > _z_blockage.back())
129  paramError("z_blockage", "z_blockage inlet location must not exceed outlet location");
130 
131  if (*max_element(_reduction_blockage.begin(), _reduction_blockage.end()) > 1)
132  paramError("reduction_blockage",
133  "The area reduction of the blocked subchannels cannot be more than 1");
134 
135  if ((_index_blockage.size() != _reduction_blockage.size()) ||
136  (_index_blockage.size() != _k_blockage.size()) ||
137  (_reduction_blockage.size() != _k_blockage.size()))
138  mooseError("Size of vectors: index_blockage, reduction_blockage, k_blockage, must be equal "
139  "to eachother");
140 
143 
144  // Defining the total length from 3 axial sections
145  Real L = total_length;
146 
147  // Defining the position of the spacer grid in the numerical solution array
148  std::vector<int> spacer_cell;
149  for (const auto & elem : _spacer_z)
150  spacer_cell.emplace_back(std::round(elem * _n_cells / L));
151 
152  // Defining the array for axial resistances
153  std::vector<Real> kgrid;
154  kgrid.resize(_n_cells + 1, 0.0);
155 
156  // Summing the spacer resistance to the grid resistance array
157  for (unsigned int index = 0; index < spacer_cell.size(); index++)
158  kgrid[spacer_cell[index]] += _spacer_k[index];
159 
160  // compute the hex mesh variables
161  // -------------------------------------------
162  // x coordinate for the first position
163  Real x0 = 0.0;
164  // y coordinate for the first position
165  Real y0 = 0.0;
166  // x coordinate for the second position
167  Real x1 = 0.0;
168  // y coordinate for the second position dummy variable
169  Real y1 = 0.0;
170  // dummy variable
171  Real a1 = 0.0;
172  // dummy variable
173  Real a2 = 0.0;
174  // average x coordinate
175  Real avg_coor_x = 0.0;
176  // average y coordinate
177  Real avg_coor_y = 0.0;
178  // distance between two points
179  Real dist = 0.0;
180  // distance between two points
181  Real dist0 = 0.0;
182  // integer counter
183  unsigned int kgap = 0;
184  // dummy integer
185  unsigned int icorner = 0;
186  // used to defined global direction of the cross_flow_map coefficients for each subchannel and gap
187  const Real positive_flow = 1.0;
188  // used to defined global direction of the cross_flow_map coefficients for each subchannel and gap
189  const Real negative_flow = -1.0;
190  // the indicator used while setting _gap_to_chan_map array
191  std::vector<std::pair<unsigned int, unsigned int>> gap_fill;
193  _npins = _pin_position.size();
194  // assign the pins to the corresponding rings
195  unsigned int k = 0; // initialize the fuel Pin counter index
196  _pins_in_rings.resize(_n_rings);
197  _pins_in_rings[0].push_back(k++);
198  for (unsigned int i = 1; i < _n_rings; i++)
199  for (unsigned int j = 0; j < i * 6; j++)
200  _pins_in_rings[i].push_back(k++);
201  // Given the number of pins and number of fuel Pin rings, the number of subchannels can be
202  // computed as follows:
203  unsigned int chancount = 0.0;
204  // Summing internal channels
205  for (unsigned int j = 0; j < _n_rings - 1; j++)
206  chancount += j * 6;
207  // Adding external channels to the total count
208  _n_channels = chancount + _npins - 1 + (_n_rings - 1) * 6 + 6;
209 
210  if (*max_element(_index_blockage.begin(), _index_blockage.end()) > (_n_channels - 1))
211  paramError("index_blockage",
212  "The index of the blocked subchannel cannot be more than the max index of the "
213  "subchannels");
214 
215  if ((_index_blockage.size() > _n_channels) || (_reduction_blockage.size() > _n_channels) ||
216  (_k_blockage.size() > _n_channels))
217  mooseError("Size of vectors: index_blockage, reduction_blockage, k_blockage, cannot be more "
218  "than the total number of subchannels");
219 
220  // Defining the 2D array for axial resistances
221  _k_grid.resize(_n_channels, std::vector<Real>(_n_cells + 1));
222  for (unsigned int i = 0; i < _n_channels; i++)
223  _k_grid[i] = kgrid;
224 
225  // Add blockage resistance to the 2D grid resistane array
226  Real dz = L / _n_cells;
227  for (unsigned int i = 0; i < _n_cells + 1; i++)
228  {
229  if ((dz * i >= _z_blockage.front() && dz * i <= _z_blockage.back()))
230  {
231  unsigned int index(0);
232  for (const auto & i_ch : _index_blockage)
233  {
234  _k_grid[i_ch][i] += _k_blockage[index];
235  index++;
236  }
237  }
238  }
239 
241  _pin_to_chan_map.resize(_npins);
242  _subch_type.resize(_n_channels);
243  _n_gaps = _n_channels + _npins - 1;
244  _gap_to_chan_map.resize(_n_gaps);
245  _gap_to_pin_map.resize(_n_gaps);
246  gap_fill.resize(_n_gaps);
248  _gap_pairs_sf.resize(_n_channels);
249  _chan_pairs_sf.resize(_n_channels);
250  _gij_map.resize(_n_cells + 1);
252  _gap_type.resize(_n_gaps);
254 
255  for (unsigned int i = 0; i < _n_channels; i++)
256  {
257  _chan_to_pin_map[i].reserve(3);
258  _chan_to_gap_map[i].reserve(3);
259  _sign_id_crossflow_map[i].reserve(3);
260  _subchannel_position[i].reserve(3);
261  for (unsigned int j = 0; j < 3; j++)
262  {
263  _sign_id_crossflow_map.at(i).push_back(positive_flow);
264  _subchannel_position.at(i).push_back(0.0);
265  }
266  }
267 
268  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
269  {
270  _gij_map[iz].reserve(_n_gaps);
271  }
272 
273  for (unsigned int i = 0; i < _npins; i++)
274  _pin_to_chan_map[i].reserve(6);
275 
276  // create the subchannels
277  k = 0; // initialize the subchannel counter index
278  kgap = 0;
279  // for each ring we trace the subchannels by pairing up to neighbor pins and looking for the third
280  // Pin at inner or outer ring compared to the current ring.
281  for (unsigned int i = 1; i < _n_rings; i++)
282  {
283  // find the closest Pin at back ring
284  for (unsigned int j = 0; j < _pins_in_rings[i].size(); j++)
285  {
286  if (j == _pins_in_rings[i].size() - 1)
287  {
288  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
289  _chan_to_pin_map[k].push_back(_pins_in_rings[i][0]);
290  avg_coor_x =
291  0.5 * (_pin_position[_pins_in_rings[i][j]](0) + _pin_position[_pins_in_rings[i][0]](0));
292  avg_coor_y =
293  0.5 * (_pin_position[_pins_in_rings[i][j]](1) + _pin_position[_pins_in_rings[i][0]](1));
294  _gap_to_pin_map[kgap].first = _pins_in_rings[i][0];
295  _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
297  kgap = kgap + 1;
298  }
299  else
300  {
301  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
302  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j + 1]);
303  avg_coor_x = 0.5 * (_pin_position[_pins_in_rings[i][j]](0) +
304  _pin_position[_pins_in_rings[i][j + 1]](0));
305  avg_coor_y = 0.5 * (_pin_position[_pins_in_rings[i][j]](1) +
306  _pin_position[_pins_in_rings[i][j + 1]](1));
307  _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
308  _gap_to_pin_map[kgap].second = _pins_in_rings[i][j + 1];
310  kgap = kgap + 1;
311  }
312 
313  dist0 = 1.0e+5;
314 
315  _chan_to_pin_map[k].push_back(_pins_in_rings[i - 1][0]);
316  unsigned int l0 = 0;
317 
318  for (unsigned int l = 0; l < _pins_in_rings[i - 1].size(); l++)
319  {
320  dist = std::sqrt(pow(_pin_position[_pins_in_rings[i - 1][l]](0) - avg_coor_x, 2) +
321  pow(_pin_position[_pins_in_rings[i - 1][l]](1) - avg_coor_y, 2));
322 
323  if (dist < dist0)
324  {
325  _chan_to_pin_map[k][2] = _pins_in_rings[i - 1][l];
326  l0 = l;
327  dist0 = dist;
328  } // if
329  } // l
330 
331  _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
332  _gap_to_pin_map[kgap].second = _pins_in_rings[i - 1][l0];
334  kgap = kgap + 1;
336  k = k + 1;
337  } // for j
338 
339  // find the closest Pin at front ring
340  for (unsigned int j = 0; j < _pins_in_rings[i].size(); j++)
341  {
342  if (j == _pins_in_rings[i].size() - 1)
343  {
344  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
345  _chan_to_pin_map[k].push_back(_pins_in_rings[i][0]);
346  avg_coor_x =
347  0.5 * (_pin_position[_pins_in_rings[i][j]](0) + _pin_position[_pins_in_rings[i][0]](0));
348  avg_coor_y =
349  0.5 * (_pin_position[_pins_in_rings[i][j]](1) + _pin_position[_pins_in_rings[i][0]](1));
350  }
351  else
352  {
353  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
354  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j + 1]);
355  avg_coor_x = 0.5 * (_pin_position[_pins_in_rings[i][j]](0) +
356  _pin_position[_pins_in_rings[i][j + 1]](0));
357  avg_coor_y = 0.5 * (_pin_position[_pins_in_rings[i][j]](1) +
358  _pin_position[_pins_in_rings[i][j + 1]](1));
359  }
360 
361  // if the outermost ring, set the edge subchannels first... then the corner subchannels
362  if (i == _n_rings - 1)
363  {
364  // add edges
365  _subch_type[k] = EChannelType::EDGE; // an edge subchannel is created
366  _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
367  _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
369  _chan_to_gap_map[k].push_back(kgap);
370  kgap = kgap + 1;
371  k = k + 1;
372 
373  if (j % i == 0)
374  {
375  // generate a corner subchannel, generate the additional gap and fix chan_to_gap_map
376  _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
377  _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
379 
380  // corner subchannel
381  _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
382  _chan_to_gap_map[k].push_back(kgap - 1);
383  _chan_to_gap_map[k].push_back(kgap);
385 
386  kgap = kgap + 1;
387  k = k + 1;
388  }
389  // if not the outer most ring
390  }
391  else
392  {
393  dist0 = 1.0e+5;
394  unsigned int l0 = 0;
395  _chan_to_pin_map[k].push_back(_pins_in_rings[i + 1][0]);
396  for (unsigned int l = 0; l < _pins_in_rings[i + 1].size(); l++)
397  {
398  dist = std::sqrt(pow(_pin_position[_pins_in_rings[i + 1][l]](0) - avg_coor_x, 2) +
399  pow(_pin_position[_pins_in_rings[i + 1][l]](1) - avg_coor_y, 2));
400  if (dist < dist0)
401  {
402  _chan_to_pin_map[k][2] = _pins_in_rings[i + 1][l];
403  dist0 = dist;
404  l0 = l;
405  } // if
406  } // l
407 
408  _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
409  _gap_to_pin_map[kgap].second = _pins_in_rings[i + 1][l0];
411  kgap = kgap + 1;
413  k = k + 1;
414  } // if
415  } // for j
416  } // for i
417 
418  // Constructing pins to channels mao
419  for (unsigned int loc_rod = 0; loc_rod < _npins; loc_rod++)
420  {
421  for (unsigned int i = 0; i < _n_channels; i++)
422  {
423  bool rod_in_sc = false;
424  for (unsigned int j : _chan_to_pin_map[i])
425  {
426  if (j == loc_rod)
427  rod_in_sc = true;
428  }
429  if (rod_in_sc)
430  {
431  _pin_to_chan_map[loc_rod].push_back(i);
432  }
433  }
434  }
435 
448  for (unsigned int i = 0; i < _n_channels; i++)
449  {
451  {
452  for (unsigned int j = 0; j < _n_gaps; j++)
453  {
455  {
456  if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
457  (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second)) ||
458  ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
459  (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first)))
460  {
461  _chan_to_gap_map[i].push_back(j);
462  }
463 
464  if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
465  (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].second)) ||
466  ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
467  (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].first)))
468  {
469  _chan_to_gap_map[i].push_back(j);
470  }
471 
472  if (((_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first) &&
473  (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].second)) ||
474  ((_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second) &&
475  (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].first)))
476  {
477  _chan_to_gap_map[i].push_back(j);
478  }
479  }
480  } // for j
481  }
482  else if (_subch_type[i] == EChannelType::EDGE)
483  {
484  for (unsigned int j = 0; j < _n_gaps; j++)
485  {
487  {
488  if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
489  (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second)) ||
490  ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
491  (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first)))
492  {
493  _chan_to_gap_map[i].push_back(j);
494  }
495  }
496  }
497 
498  icorner = 0;
499  for (unsigned int k = 0; k < _n_channels; k++)
500  {
502  _chan_to_pin_map[i][1] == _chan_to_pin_map[k][0])
503  {
504  _chan_to_gap_map[i].push_back(_chan_to_gap_map[k][1]);
505  icorner = 1;
506  break;
507  } // if
508  } // for
509 
510  // Check whether the edge channel's first pin is also a corner pin. This second corner lookup
511  // is only needed while the edge channel still needs another perimeter gap.
512  if (_chan_to_gap_map[i].size() < 3)
513  {
514  for (unsigned int k = 0; k < _n_channels; k++)
515  {
517  _chan_to_pin_map[i][0] == _chan_to_pin_map[k][0])
518  {
519  _chan_to_gap_map[i].push_back(_chan_to_gap_map[k][1] + 1);
520  icorner = 1;
521  break;
522  }
523  }
524  }
525 
526  if (icorner == 0)
527  {
528  _chan_to_gap_map[i].push_back(_chan_to_gap_map[i][0] + 1);
529  }
530  }
531  }
532 
533  // find gap_to_chan_map pair
534  for (unsigned int j = 0; j < _n_gaps; j++)
535  {
536  for (unsigned int i = 0; i < _n_channels; i++)
537  {
539  {
540  if ((j == _chan_to_gap_map[i][0]) || (j == _chan_to_gap_map[i][1]) ||
541  (j == _chan_to_gap_map[i][2]))
542  {
543  if (_gap_to_chan_map[j].first == 0 && gap_fill[j].first == 0)
544  {
545  _gap_to_chan_map[j].first = i;
546  gap_fill[j].first = 1;
547  }
548  else if (_gap_to_chan_map[j].second == 0 && gap_fill[j].second == 0)
549  {
550  _gap_to_chan_map[j].second = i;
551  gap_fill[j].second = 1;
552  }
553  else
554  {
555  }
556  }
557  }
558  else if (_subch_type[i] == EChannelType::CORNER)
559  {
560  if ((j == _chan_to_gap_map[i][0]) || (j == _chan_to_gap_map[i][1]))
561  {
562  if (_gap_to_chan_map[j].first == 0 && gap_fill[j].first == 0)
563  {
564  _gap_to_chan_map[j].first = i;
565  gap_fill[j].first = 1;
566  }
567  else if (_gap_to_chan_map[j].second == 0 && gap_fill[j].second == 0)
568  {
569  _gap_to_chan_map[j].second = i;
570  gap_fill[j].second = 1;
571  }
572  else
573  {
574  }
575  }
576  }
577  } // i
578  } // j
579 
580  for (unsigned int k = 0; k < _n_channels; k++)
581  {
583  {
584  _gap_pairs_sf[k].first = _chan_to_gap_map[k][0];
585  _gap_pairs_sf[k].second = _chan_to_gap_map[k][2];
586  auto k1 = _gap_pairs_sf[k].first;
587  auto k2 = _gap_pairs_sf[k].second;
588  if (_gap_to_chan_map[k1].first == k)
589  {
590  _chan_pairs_sf[k].first = _gap_to_chan_map[k1].second;
591  }
592  else
593  {
594  _chan_pairs_sf[k].first = _gap_to_chan_map[k1].first;
595  }
596 
597  if (_gap_to_chan_map[k2].first == k)
598  {
599  _chan_pairs_sf[k].second = _gap_to_chan_map[k2].second;
600  }
601  else
602  {
603  _chan_pairs_sf[k].second = _gap_to_chan_map[k2].first;
604  }
605  }
606  else if (_subch_type[k] == EChannelType::CORNER)
607  {
608  _gap_pairs_sf[k].first = _chan_to_gap_map[k][1];
609  _gap_pairs_sf[k].second = _chan_to_gap_map[k][0];
610 
611  auto k1 = _gap_pairs_sf[k].first;
612  auto k2 = _gap_pairs_sf[k].second;
613 
614  if (_gap_to_chan_map[k1].first == k)
615  {
616  _chan_pairs_sf[k].first = _gap_to_chan_map[k1].second;
617  }
618  else
619  {
620  _chan_pairs_sf[k].first = _gap_to_chan_map[k1].first;
621  }
622 
623  if (_gap_to_chan_map[k2].first == k)
624  {
625  _chan_pairs_sf[k].second = _gap_to_chan_map[k2].second;
626  }
627  else
628  {
629  _chan_pairs_sf[k].second = _gap_to_chan_map[k2].first;
630  }
631  }
632  }
633 
634  // set the _gij_map
635  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
636  {
637  for (unsigned int i_gap = 0; i_gap < _n_gaps; i_gap++)
638  {
639  if (_gap_type[i_gap] == EChannelType::CENTER)
640  {
641  _gij_map[iz].push_back(_pitch - _pin_diameter);
642  }
643  else if (_gap_type[i_gap] == EChannelType::EDGE || _gap_type[i_gap] == EChannelType::CORNER)
644  {
645  _gij_map[iz].push_back(_duct_to_pin_gap);
646  }
647  }
648  }
649 
650  for (unsigned int i = 0; i < _n_channels; i++)
651  {
653  {
654  for (unsigned int k = 0; k < 3; k++)
655  {
656  for (unsigned int j = 0; j < _n_gaps; j++)
657  {
658  if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].first)
659  {
660  if (i > _gap_to_chan_map[j].second)
661  {
662  _sign_id_crossflow_map[i][k] = negative_flow;
663  }
664  else
665  {
666  _sign_id_crossflow_map[i][k] = positive_flow;
667  }
668  }
669  else if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].second)
670  {
671  if (i > _gap_to_chan_map[j].first)
672  {
673  _sign_id_crossflow_map[i][k] = negative_flow;
674  }
675  else
676  {
677  _sign_id_crossflow_map[i][k] = positive_flow;
678  }
679  }
680  } // j
681  } // k
682  }
683  else if (_subch_type[i] == EChannelType::CORNER)
684  {
685  for (unsigned int k = 0; k < 2; k++)
686  {
687  for (unsigned int j = 0; j < _n_gaps; j++)
688  {
689  if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].first)
690  {
691  if (i > _gap_to_chan_map[j].second)
692  {
693  _sign_id_crossflow_map[i][k] = negative_flow;
694  }
695  else
696  {
697  _sign_id_crossflow_map[i][k] = positive_flow;
698  }
699  }
700  else if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].second)
701  {
702  if (i > _gap_to_chan_map[j].first)
703  {
704  _sign_id_crossflow_map[i][k] = negative_flow;
705  }
706  else
707  {
708  _sign_id_crossflow_map[i][k] = positive_flow;
709  }
710  }
711  } // j
712  } // k
713  } // subch_type =2
714  } // i
715 
716  // set the subchannel positions
717  for (unsigned int i = 0; i < _n_channels; i++)
718  {
720  {
721  _subchannel_position[i][0] =
723  _pin_position[_chan_to_pin_map[i][2]](0)) /
724  3.0;
725  _subchannel_position[i][1] =
727  _pin_position[_chan_to_pin_map[i][2]](1)) /
728  3.0;
729  }
730  else if (_subch_type[i] == EChannelType::EDGE)
731  {
732  for (unsigned int j = 0; j < _n_channels; j++)
733  {
735  ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][0] &&
736  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][1]) ||
737  (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][1] &&
738  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][0])))
739  {
740  x0 = _pin_position[_chan_to_pin_map[j][2]](0);
741  y0 = _pin_position[_chan_to_pin_map[j][2]](1);
742  }
743  else if (_subch_type[j] == EChannelType::CENTER &&
744  ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][0] &&
745  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][2]) ||
746  (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][2] &&
747  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][0])))
748  {
749  x0 = _pin_position[_chan_to_pin_map[j][1]](0);
750  y0 = _pin_position[_chan_to_pin_map[j][1]](1);
751  }
752  else if (_subch_type[j] == EChannelType::CENTER &&
753  ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][1] &&
754  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][2]) ||
755  (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][2] &&
756  _chan_to_pin_map[i][1] == _chan_to_pin_map[j][1])))
757  {
758  x0 = _pin_position[_chan_to_pin_map[j][0]](0);
759  y0 = _pin_position[_chan_to_pin_map[j][0]](1);
760  }
761  x1 = 0.5 *
763  y1 = 0.5 *
765  a1 = _pin_diameter / 2.0 + _duct_to_pin_gap / 2.0;
766  a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
767  _subchannel_position[i][0] = (a2 * x1 - a1 * x0) / (a2 - a1);
768  _subchannel_position[i][1] = (a2 * y1 - a1 * y0) / (a2 - a1);
769  } // j
770  }
771  else if (_subch_type[i] == EChannelType::CORNER)
772  {
773  x0 = _pin_position[0](0);
774  y0 = _pin_position[0](1);
775  x1 = _pin_position[_chan_to_pin_map[i][0]](0);
776  y1 = _pin_position[_chan_to_pin_map[i][0]](1);
777  a1 = _pin_diameter / 2.0 + _duct_to_pin_gap / 2.0;
778  a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
779  _subchannel_position[i][0] = (a2 * x1 - a1 * x0) / (a2 - a1);
780  _subchannel_position[i][1] = (a2 * y1 - a1 * y0) / (a2 - a1);
781  }
782  }
783 
784  // Reduce reserved memory in the channel-to-gap map.
785  for (auto & gap : _chan_to_gap_map)
786  {
787  gap.shrink_to_fit();
788  }
789 }
const Real _flat_to_flat
the distance between flat surfaces of the duct facing each other
const std::vector< Real > & _spacer_k
form loss coefficient of the spacers
const unsigned int _subchannel_block_id
subchannel block index
void paramError(const std::string &param, Args... args) const
const T & getParam(const std::string &name) const
std::vector< std::vector< unsigned int > > _chan_to_gap_map
stores the gaps that forms each subchannel
const std::vector< Real > & _spacer_z
axial location of the spacers
std::vector< std::pair< unsigned int, unsigned int > > _chan_pairs_sf
sweeping flow model channel pairs to specify directional edge flow
std::vector< std::vector< Real > > _pins_in_rings
fuel pins that are belonging to each ring
const Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
static void pinPositions(std::vector< Point > &positions, unsigned int nrings, Real pitch, Point center)
Calculates and stores the pin positions/centers for a hexagonal assembly containing the given number ...
const unsigned int _n_rings
number of rings of fuel pins
std::vector< std::vector< unsigned int > > _chan_to_pin_map
stores the fuel pins belonging to each subchannel
MeshGenerator(const InputParameters &parameters)
std::vector< EChannelType > _subch_type
subchannel type
std::vector< std::vector< unsigned int > > _pin_to_chan_map
stores the map from pins to channels
const std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
const Real _hwire
wire lead length
const Real _pitch
Distance between the neighbor fuel pins, pitch.
const std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
static void generateZGrid(Real unheated_length_entry, Real heated_length, Real unheated_length_exit, unsigned int n_cells, std::vector< Real > &z_grid)
Generate the spacing in z-direction using heated and unteaded lengths.
const unsigned int _n_cells
number of axial cells
const std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
unsigned int _n_channels
number of subchannels
std::vector< std::vector< Real > > _sign_id_crossflow_map
Defines the global cross-flow direction -1 or 1 for each subchannel and for all gaps that are belongi...
std::vector< EChannelType > _gap_type
gap type
const Real _duct_to_pin_gap
the gap thickness between the duct and peripheral fuel pins
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
const unsigned int _pin_block_id
pin block index
const std::vector< Real > _k_blockage
form loss coefficient of subchannels affected by blockage
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< std::vector< Real > > _gij_map
gap size
const Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< Real > _z_grid
axial location of nodes
void mooseError(Args &&... args) const
const Real _pin_diameter
fuel Pin diameter
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
stores the channel pairs for each gap
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const Real & _kij
Lateral form loss coefficient.
std::vector< Point > _pin_position
x,y coordinates of the fuel pins
unsigned int _n_gaps
number of gaps
static const std::string k
Definition: NS.h:134
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
std::vector< std::pair< unsigned int, unsigned int > > _gap_pairs_sf
sweeping flow model gap pairs per channel to specify directional edge flow
const Real _heated_length
heated length of the fuel Pin
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
stores the fuel pin pairs for each gap each gap
unsigned int _npins
number of fuel pins
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell

Member Function Documentation

◆ buildPinMesh()

void SCMTriAssemblyMeshGenerator::buildPinMesh ( MeshBase &  mesh_base)
protected

Build the 1D pin elements and append them to the subchannel mesh.

Definition at line 792 of file SCMTriAssemblyMeshGenerator.C.

Referenced by generate().

793 {
794  if (_npins == 0)
795  return;
796 
797  mesh_base.reserve_elem(_n_cells * _npins);
798  mesh_base.reserve_nodes((_n_cells + 1) * _npins);
799 
800  _pin_nodes.clear();
801  _pin_nodes.resize(_npins);
802 
803  // Defining the extent of the subchannel mesh to append the pin mesh to the current subchannel
804  // mesh.
805  const unsigned int node_sub = mesh_base.n_nodes();
806  const unsigned int elem_sub = mesh_base.n_elem();
807 
808  // Add the points in the shape of a rectilinear grid. The grid is regular on the xy-plane at the
809  // triangular lattice pin positions. The grid along z is also regular. Store pointers in the
810  // _pin_nodes array so we can keep track of which points are in which pins.
811  unsigned int node_id = node_sub;
812  for (unsigned int i = 0; i < _npins; i++)
813  {
814  _pin_nodes[i].reserve(_n_cells + 1);
815  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
816  _pin_nodes[i].push_back(mesh_base.add_point(
817  Point(_pin_position[i](0), _pin_position[i](1), _z_grid[iz]), node_id++));
818  }
819 
820  // Add the elements which in this case are 2-node edges that link each pin's nodes vertically.
821  unsigned int elem_id = elem_sub;
822  for (unsigned int i = 0; i < _npins; i++)
823  for (unsigned int iz = 0; iz < _n_cells; iz++)
824  {
825  Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
826  elem->subdomain_id() = _pin_block_id;
827  elem->set_id(elem_id++);
828  const int indx1 = (_n_cells + 1) * i + iz + node_sub;
829  const int indx2 = (_n_cells + 1) * i + (iz + 1) + node_sub;
830  elem->set_node(0, mesh_base.node_ptr(indx1));
831  elem->set_node(1, mesh_base.node_ptr(indx2));
832  }
833 
834  mesh_base.subdomain_name(_pin_block_id) = "fuel_pins";
835 }
const unsigned int _n_cells
number of axial cells
const unsigned int _pin_block_id
pin block index
std::vector< Real > _z_grid
axial location of nodes
std::vector< std::vector< Node * > > _pin_nodes
pin nodes
std::vector< Point > _pin_position
x,y coordinates of the fuel pins
unsigned int _npins
number of fuel pins

◆ generate()

std::unique_ptr< MeshBase > SCMTriAssemblyMeshGenerator::generate ( )
overridevirtual

Implements MeshGenerator.

Definition at line 838 of file SCMTriAssemblyMeshGenerator.C.

839 {
840  auto mesh_base = buildMeshBaseObject();
841 
842  BoundaryInfo & boundary_info = mesh_base->get_boundary_info();
843  mesh_base->set_spatial_dimension(3);
844  mesh_base->reserve_elem(_n_cells * (_n_channels + _npins));
845  mesh_base->reserve_nodes((_n_cells + 1) * (_n_channels + _npins));
846  _nodes.resize(_n_channels);
847  // Add the points for the give x,y subchannel positions. The grid is hexagonal.
848  // The grid along
849  // z is irregular to account for Pin spacers. Store pointers in the _nodes
850  // array so we can keep track of which points are in which channels.
851  unsigned int node_id = 0;
852  for (unsigned int i = 0; i < _n_channels; i++)
853  {
854  _nodes[i].reserve(_n_cells + 1);
855  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
856  {
857  _nodes[i].push_back(mesh_base->add_point(
858  Point(_subchannel_position[i][0], _subchannel_position[i][1], _z_grid[iz]), node_id++));
859  }
860  }
861 
862  // Add the elements which in this case are 2-node edges that link each
863  // subchannel's nodes vertically.
864  unsigned int elem_id = 0;
865  for (unsigned int i = 0; i < _n_channels; i++)
866  {
867  for (unsigned int iz = 0; iz < _n_cells; iz++)
868  {
869  Elem * elem = mesh_base->add_elem(std::make_unique<Edge2>());
870  elem->subdomain_id() = _subchannel_block_id;
871  elem->set_id(elem_id++);
872  const int indx1 = (_n_cells + 1) * i + iz;
873  const int indx2 = (_n_cells + 1) * i + (iz + 1);
874  elem->set_node(0, mesh_base->node_ptr(indx1));
875  elem->set_node(1, mesh_base->node_ptr(indx2));
876 
877  if (iz == 0)
878  boundary_info.add_side(elem, 0, 0);
879  if (iz == _n_cells - 1)
880  boundary_info.add_side(elem, 1, 1);
881  }
882  }
883  boundary_info.sideset_name(0) = "inlet";
884  boundary_info.sideset_name(1) = "outlet";
885  boundary_info.nodeset_name(0) = "inlet";
886  boundary_info.nodeset_name(1) = "outlet";
887 
888  // Naming the block
889  mesh_base->subdomain_name(_subchannel_block_id) = "subchannel";
890  buildPinMesh(*mesh_base);
891 
892  mesh_base->prepare_for_use();
893 
894  // move the meta data into TriSubChannelMesh
895  auto & sch_mesh = static_cast<TriSubChannelMesh &>(*_mesh);
897  sch_mesh._heated_length = _heated_length;
898  sch_mesh._unheated_length_exit = _unheated_length_exit;
899  sch_mesh._z_grid = _z_grid;
900  sch_mesh._k_grid = _k_grid;
901  sch_mesh._spacer_z = _spacer_z;
902  sch_mesh._spacer_k = _spacer_k;
903  sch_mesh._z_blockage = _z_blockage;
904  sch_mesh._index_blockage = _index_blockage;
905  sch_mesh._reduction_blockage = _reduction_blockage;
906  sch_mesh._kij = _kij;
907  sch_mesh._pitch = _pitch;
908  sch_mesh._pin_diameter = _pin_diameter;
909  sch_mesh._n_cells = _n_cells;
910  sch_mesh._n_rings = _n_rings;
911  sch_mesh._n_channels = _n_channels;
912  sch_mesh._flat_to_flat = _flat_to_flat;
913  sch_mesh._dwire = _dwire;
914  sch_mesh._hwire = _hwire;
915  sch_mesh._duct_to_pin_gap = _duct_to_pin_gap;
916  sch_mesh._nodes = _nodes;
917  sch_mesh._gap_to_chan_map = _gap_to_chan_map;
918  sch_mesh._gap_to_pin_map = _gap_to_pin_map;
919  sch_mesh._chan_to_gap_map = _chan_to_gap_map;
920  sch_mesh._sign_id_crossflow_map = _sign_id_crossflow_map;
921  sch_mesh._gij_map = _gij_map;
922  sch_mesh._subchannel_position = _subchannel_position;
923  sch_mesh._pin_position = _pin_position;
924  sch_mesh._pins_in_rings = _pins_in_rings;
925  sch_mesh._chan_to_pin_map = _chan_to_pin_map;
926  sch_mesh._npins = _npins;
927  sch_mesh._n_gaps = _n_gaps;
928  sch_mesh._subch_type = _subch_type;
929  sch_mesh._gap_type = _gap_type;
930  sch_mesh._gap_pairs_sf = _gap_pairs_sf;
931  sch_mesh._chan_pairs_sf = _chan_pairs_sf;
932  sch_mesh._pin_to_chan_map = _pin_to_chan_map;
933  sch_mesh._pin_nodes = _pin_nodes;
934  sch_mesh._pin_mesh_exist = (_npins > 0);
935  sch_mesh.computeAssemblyHydraulicParameters();
936 
937  return mesh_base;
938 }
const Real _flat_to_flat
the distance between flat surfaces of the duct facing each other
const std::vector< Real > & _spacer_k
form loss coefficient of the spacers
const unsigned int _subchannel_block_id
subchannel block index
std::vector< std::vector< unsigned int > > _chan_to_gap_map
stores the gaps that forms each subchannel
const std::vector< Real > & _spacer_z
axial location of the spacers
std::vector< std::pair< unsigned int, unsigned int > > _chan_pairs_sf
sweeping flow model channel pairs to specify directional edge flow
std::vector< std::vector< Real > > _pins_in_rings
fuel pins that are belonging to each ring
const Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
const unsigned int _n_rings
number of rings of fuel pins
std::vector< std::vector< unsigned int > > _chan_to_pin_map
stores the fuel pins belonging to each subchannel
Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
std::vector< EChannelType > _subch_type
subchannel type
std::vector< std::vector< unsigned int > > _pin_to_chan_map
stores the map from pins to channels
void buildPinMesh(MeshBase &mesh_base)
Build the 1D pin elements and append them to the subchannel mesh.
const std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
const Real _hwire
wire lead length
const Real _pitch
Distance between the neighbor fuel pins, pitch.
const std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
const unsigned int _n_cells
number of axial cells
const std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
unsigned int _n_channels
number of subchannels
std::vector< std::vector< Real > > _sign_id_crossflow_map
Defines the global cross-flow direction -1 or 1 for each subchannel and for all gaps that are belongi...
std::vector< EChannelType > _gap_type
gap type
const Real _duct_to_pin_gap
the gap thickness between the duct and peripheral fuel pins
Mesh class for triangular, edge and corner subchannels for hexagonal lattice fuel assemblies...
std::vector< std::vector< Real > > _gij_map
gap size
const Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< Real > _z_grid
axial location of nodes
std::vector< std::vector< Node * > > _pin_nodes
pin nodes
const Real _pin_diameter
fuel Pin diameter
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
stores the channel pairs for each gap
std::vector< std::vector< Node * > > _nodes
nodes
const Real & _kij
Lateral form loss coefficient.
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
std::vector< Point > _pin_position
x,y coordinates of the fuel pins
unsigned int _n_gaps
number of gaps
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
std::vector< std::pair< unsigned int, unsigned int > > _gap_pairs_sf
sweeping flow model gap pairs per channel to specify directional edge flow
const Real _heated_length
heated length of the fuel Pin
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
stores the fuel pin pairs for each gap each gap
unsigned int _npins
number of fuel pins
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell

◆ validParams()

InputParameters SCMTriAssemblyMeshGenerator::validParams ( )
static

Definition at line 36 of file SCMTriAssemblyMeshGenerator.C.

37 {
39  params.addClassDescription(
40  "Creates a mesh of 1D subchannels and 1D pins in a triangular lattice arrangement");
41  params.addRequiredParam<unsigned int>("n_cells", "The number of cells in the axial direction");
42  params.addRequiredParam<Real>("pitch", "Pitch [m]");
43  params.addRequiredParam<Real>("pin_diameter", "Rod diameter [m]");
44  params.addParam<Real>("unheated_length_entry", 0.0, "Unheated length at entry [m]");
45  params.addRequiredParam<Real>("heated_length", "Heated length [m]");
46  params.addParam<Real>("unheated_length_exit", 0.0, "Unheated length at exit [m]");
47  params.addRequiredParam<unsigned int>(
48  "nrings",
49  "Number of fuel-pin rings per assembly, counting the center pin as the first ring [-]");
50  params.addRequiredParam<Real>("flat_to_flat",
51  "Flat to flat distance for the hexagonal assembly [m]");
52  params.addRequiredParam<Real>("dwire", "Wire diameter [m]");
53  params.addRequiredParam<Real>("hwire", "Wire lead length [m]");
54  params.addParam<std::vector<Real>>(
55  "spacer_z", {}, "Axial location of spacers/vanes/mixing vanes [m]");
56  params.addParam<std::vector<Real>>(
57  "spacer_k", {}, "K-loss coefficient of spacers/vanes/mixing vanes [-]");
58  params.addParam<Real>("Kij", 0.5, "Lateral form loss coefficient [-]");
59  params.addParam<std::vector<Real>>("z_blockage",
60  std::vector<Real>({0.0, 0.0}),
61  "axial location of blockage (inlet, outlet) [m]");
62  params.addParam<std::vector<unsigned int>>("index_blockage",
63  std::vector<unsigned int>({0}),
64  "index of subchannels affected by blockage");
65  params.addParam<std::vector<Real>>(
66  "reduction_blockage",
67  std::vector<Real>({1.0}),
68  "Area reduction of subchannels affected by blockage (number to muliply the area)");
69  params.addParam<std::vector<Real>>("k_blockage",
70  std::vector<Real>({0.0}),
71  "Form loss coefficient of subchannels affected by blockage");
72  params.addParam<unsigned int>("block_id", 0, "Subchannel block id");
73  params.deprecateParam("block_id", "subchannel_block_id", "07/01/2027");
74  params.addParam<unsigned int>("pin_block_id", 1, "Fuel Pin block id");
75  return params;
76 }
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addClassDescription(const std::string &doc_string)

Member Data Documentation

◆ _chan_pairs_sf

std::vector<std::pair<unsigned int, unsigned int> > SCMTriAssemblyMeshGenerator::_chan_pairs_sf
protected

sweeping flow model channel pairs to specify directional edge flow

Definition at line 115 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _chan_to_gap_map

std::vector<std::vector<unsigned int> > SCMTriAssemblyMeshGenerator::_chan_to_gap_map
protected

stores the gaps that forms each subchannel

Definition at line 86 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _chan_to_pin_map

std::vector<std::vector<unsigned int> > SCMTriAssemblyMeshGenerator::_chan_to_pin_map
protected

stores the fuel pins belonging to each subchannel

Definition at line 101 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _duct_to_pin_gap

const Real SCMTriAssemblyMeshGenerator::_duct_to_pin_gap
protected

the gap thickness between the duct and peripheral fuel pins

Definition at line 75 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _dwire

const Real SCMTriAssemblyMeshGenerator::_dwire
protected

wire diameter

Definition at line 71 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _flat_to_flat

const Real SCMTriAssemblyMeshGenerator::_flat_to_flat
protected

the distance between flat surfaces of the duct facing each other

Definition at line 69 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _gap_pairs_sf

std::vector<std::pair<unsigned int, unsigned int> > SCMTriAssemblyMeshGenerator::_gap_pairs_sf
protected

sweeping flow model gap pairs per channel to specify directional edge flow

Definition at line 113 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _gap_to_chan_map

std::vector<std::pair<unsigned int, unsigned int> > SCMTriAssemblyMeshGenerator::_gap_to_chan_map
protected

stores the channel pairs for each gap

Definition at line 82 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _gap_to_pin_map

std::vector<std::pair<unsigned int, unsigned int> > SCMTriAssemblyMeshGenerator::_gap_to_pin_map
protected

stores the fuel pin pairs for each gap each gap

Definition at line 84 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _gap_type

std::vector<EChannelType> SCMTriAssemblyMeshGenerator::_gap_type
protected

gap type

Definition at line 111 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _gij_map

std::vector<std::vector<Real> > SCMTriAssemblyMeshGenerator::_gij_map
protected

gap size

Definition at line 93 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _heated_length

const Real SCMTriAssemblyMeshGenerator::_heated_length
protected

heated length of the fuel Pin

Definition at line 33 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _hwire

const Real SCMTriAssemblyMeshGenerator::_hwire
protected

wire lead length

Definition at line 73 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _index_blockage

const std::vector<unsigned int> SCMTriAssemblyMeshGenerator::_index_blockage
protected

index of subchannels affected by blockage

Definition at line 51 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _k_blockage

const std::vector<Real> SCMTriAssemblyMeshGenerator::_k_blockage
protected

form loss coefficient of subchannels affected by blockage

Definition at line 55 of file SCMTriAssemblyMeshGenerator.h.

Referenced by SCMTriAssemblyMeshGenerator().

◆ _k_grid

std::vector<std::vector<Real> > SCMTriAssemblyMeshGenerator::_k_grid
protected

axial form loss coefficient per computational cell

Definition at line 43 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _kij

const Real& SCMTriAssemblyMeshGenerator::_kij
protected

Lateral form loss coefficient.

Definition at line 59 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _n_cells

const unsigned int SCMTriAssemblyMeshGenerator::_n_cells
protected

number of axial cells

Definition at line 63 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh(), generate(), and SCMTriAssemblyMeshGenerator().

◆ _n_channels

unsigned int SCMTriAssemblyMeshGenerator::_n_channels
protected

number of subchannels

Definition at line 67 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _n_gaps

unsigned int SCMTriAssemblyMeshGenerator::_n_gaps
protected

number of gaps

Definition at line 107 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _n_rings

const unsigned int SCMTriAssemblyMeshGenerator::_n_rings
protected

number of rings of fuel pins

Definition at line 65 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _nodes

std::vector<std::vector<Node *> > SCMTriAssemblyMeshGenerator::_nodes
protected

nodes

Definition at line 78 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _npins

unsigned int SCMTriAssemblyMeshGenerator::_npins
protected

number of fuel pins

Definition at line 105 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh(), generate(), and SCMTriAssemblyMeshGenerator().

◆ _pin_block_id

const unsigned int SCMTriAssemblyMeshGenerator::_pin_block_id
protected

pin block index

Definition at line 39 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh().

◆ _pin_diameter

const Real SCMTriAssemblyMeshGenerator::_pin_diameter
protected

fuel Pin diameter

Definition at line 61 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _pin_nodes

std::vector<std::vector<Node *> > SCMTriAssemblyMeshGenerator::_pin_nodes
protected

pin nodes

Definition at line 80 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh(), and generate().

◆ _pin_position

std::vector<Point> SCMTriAssemblyMeshGenerator::_pin_position
protected

x,y coordinates of the fuel pins

Definition at line 97 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh(), generate(), and SCMTriAssemblyMeshGenerator().

◆ _pin_to_chan_map

std::vector<std::vector<unsigned int> > SCMTriAssemblyMeshGenerator::_pin_to_chan_map
protected

stores the map from pins to channels

Definition at line 103 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _pins_in_rings

std::vector<std::vector<Real> > SCMTriAssemblyMeshGenerator::_pins_in_rings
protected

fuel pins that are belonging to each ring

Definition at line 99 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _pitch

const Real SCMTriAssemblyMeshGenerator::_pitch
protected

Distance between the neighbor fuel pins, pitch.

Definition at line 57 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _reduction_blockage

const std::vector<Real> SCMTriAssemblyMeshGenerator::_reduction_blockage
protected

area reduction of subchannels affected by blockage

Definition at line 53 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _sign_id_crossflow_map

std::vector<std::vector<Real> > SCMTriAssemblyMeshGenerator::_sign_id_crossflow_map
protected

Defines the global cross-flow direction -1 or 1 for each subchannel and for all gaps that are belonging to the corresponding subchannel.

Given a subchannel and a gap, if the neighbor subchannel index belonging to the same gap is lower, set it to -1, otherwise set it to 1.

Definition at line 91 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _spacer_k

const std::vector<Real>& SCMTriAssemblyMeshGenerator::_spacer_k
protected

form loss coefficient of the spacers

Definition at line 47 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _spacer_z

const std::vector<Real>& SCMTriAssemblyMeshGenerator::_spacer_z
protected

axial location of the spacers

Definition at line 45 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _subch_type

std::vector<EChannelType> SCMTriAssemblyMeshGenerator::_subch_type
protected

subchannel type

Definition at line 109 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _subchannel_block_id

const unsigned int SCMTriAssemblyMeshGenerator::_subchannel_block_id
protected

subchannel block index

Definition at line 37 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate().

◆ _subchannel_position

std::vector<std::vector<Real> > SCMTriAssemblyMeshGenerator::_subchannel_position
protected

x,y coordinates of the subchannel centroids

Definition at line 95 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _unheated_length_entry

const Real SCMTriAssemblyMeshGenerator::_unheated_length_entry
protected

unheated length of the fuel Pin at the entry of the assembly

Definition at line 31 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _unheated_length_exit

const Real SCMTriAssemblyMeshGenerator::_unheated_length_exit
protected

unheated length of the fuel Pin at the exit of the assembly

Definition at line 35 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _z_blockage

const std::vector<Real> SCMTriAssemblyMeshGenerator::_z_blockage
protected

axial location of blockage (inlet, outlet) [m]

Definition at line 49 of file SCMTriAssemblyMeshGenerator.h.

Referenced by generate(), and SCMTriAssemblyMeshGenerator().

◆ _z_grid

std::vector<Real> SCMTriAssemblyMeshGenerator::_z_grid
protected

axial location of nodes

Definition at line 41 of file SCMTriAssemblyMeshGenerator.h.

Referenced by buildPinMesh(), generate(), and SCMTriAssemblyMeshGenerator().


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