LCOV - code coverage report
Current view: top level - src/meshgenerators - SCMTriInterWrapperMeshGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose subchannel: #31405 (292dce) with base fef103 Lines: 349 361 96.7 %
Date: 2025-09-04 07:58:06 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "SCMTriInterWrapperMeshGenerator.h"
      11             : #include "TriInterWrapperMesh.h"
      12             : #include <cmath>
      13             : #include "libmesh/edge_edge2.h"
      14             : #include "libmesh/unstructured_mesh.h"
      15             : 
      16             : registerMooseObject("SubChannelApp", SCMTriInterWrapperMeshGenerator);
      17             : registerMooseObjectRenamed("SubChannelApp",
      18             :                            TriInterWrapperMeshGenerator,
      19             :                            "06/30/2025 24:00",
      20             :                            SCMTriInterWrapperMeshGenerator);
      21             : 
      22             : InputParameters
      23          96 : SCMTriInterWrapperMeshGenerator::validParams()
      24             : {
      25          96 :   InputParameters params = MeshGenerator::validParams();
      26          96 :   params.addClassDescription(
      27             :       "Creates a mesh for the inter-wrapper around triangular subassemblies");
      28         192 :   params.addRequiredParam<unsigned int>("n_cells", "The number of cells in the axial direction");
      29         192 :   params.addRequiredParam<Real>("assembly_pitch", "Pitch [m]");
      30         192 :   params.addParam<Real>("unheated_length_entry", 0.0, "Unheated length at entry [m]");
      31         192 :   params.addRequiredParam<Real>("heated_length", "Heated length [m]");
      32         192 :   params.addParam<Real>("unheated_length_exit", 0.0, "Unheated length at exit [m]");
      33         192 :   params.addRequiredParam<unsigned int>("nrings", "Number of fuel Pin rings per assembly [-]");
      34         192 :   params.addRequiredParam<Real>("flat_to_flat",
      35             :                                 "Flat to flat distance for the hexagonal assembly [m]");
      36         192 :   params.addParam<Real>("Kij", 0.5, "Lateral form loss coefficient [-]");
      37         192 :   params.addRequiredParam<Real>("side_bypass",
      38             :                                 "Extra size of the bypass for the side assemblies [m]");
      39         192 :   params.addParam<bool>(
      40             :       "tight_side_bypass",
      41         192 :       false,
      42             :       "Whether the side bypass shape follows the hexagonal shape of the assemblies");
      43          96 :   return params;
      44           0 : }
      45             : 
      46          48 : SCMTriInterWrapperMeshGenerator::SCMTriInterWrapperMeshGenerator(const InputParameters & params)
      47             :   : MeshGenerator(params),
      48          48 :     _unheated_length_entry(getParam<Real>("unheated_length_entry")),
      49          96 :     _heated_length(getParam<Real>("heated_length")),
      50          96 :     _unheated_length_exit(getParam<Real>("unheated_length_exit")),
      51          96 :     _kij(getParam<Real>("Kij")),
      52          96 :     _assembly_pitch(getParam<Real>("assembly_pitch")),
      53          96 :     _n_cells(getParam<unsigned int>("n_cells")),
      54          96 :     _n_rings(getParam<unsigned int>("nrings")),
      55          96 :     _flat_to_flat(getParam<Real>("flat_to_flat")),
      56          96 :     _duct_to_pin_gap(getParam<Real>("side_bypass")),
      57         144 :     _tight_side_bypass(getParam<bool>("tight_side_bypass"))
      58             : {
      59             : 
      60          48 :   InterWrapperMesh::generateZGrid(
      61          48 :       _unheated_length_entry, _heated_length, _unheated_length_exit, _n_cells, _z_grid);
      62             : 
      63             :   //  compute the hex mesh variables
      64             :   // -------------------------------------------
      65             : 
      66             :   // x coordinate for the first position
      67             :   Real x0 = 0.0;
      68             :   // y coordinate for the first position
      69             :   Real y0 = 0.0;
      70             :   // x coordinate for the second position
      71             :   Real x1 = 0.0;
      72             :   // y coordinate for the second position dummy variable
      73             :   Real y1 = 0.0;
      74             :   // dummy variable
      75             :   Real a1 = 0.0;
      76             :   // dummy variable
      77             :   Real a2 = 0.0;
      78             :   // average x coordinate
      79             :   Real avg_coor_x = 0.0;
      80             :   // average y coordinate
      81             :   Real avg_coor_y = 0.0;
      82             :   // distance between two points
      83             :   Real dist = 0.0;
      84             :   // distance between two points
      85             :   Real dist0 = 0.0;
      86             :   // integer counter
      87          48 :   unsigned int kgap = 0;
      88             :   // dummy integer
      89             :   unsigned int icorner = 0;
      90             :   // used to defined global direction of the cross_flow_map coefficients for each subchannel and gap
      91          48 :   const Real positive_flow = 1.0;
      92             :   // used to defined global direction of the cross_flow_map coefficients for each subchannel and gap
      93             :   const Real negative_flow = -1.0;
      94             :   // the indicator used while setting _gap_to_chan_map array
      95             :   std::vector<std::pair<unsigned int, unsigned int>> gap_fill;
      96          48 :   TriInterWrapperMesh::rodPositions(_pin_position, _n_rings, _assembly_pitch, Point(0, 0));
      97          48 :   _n_assemblies = _pin_position.size();
      98             :   // assign the assemblies to the corresponding rings
      99             :   // TODO: add corner to the hexagonal assemblies
     100             :   unsigned int k = 0; // initialize the fuel assembly counter index
     101          48 :   _pins_in_rings.resize(_n_rings);
     102          48 :   _pins_in_rings[0].push_back(k++);
     103         153 :   for (unsigned int i = 1; i < _n_rings; i++)
     104        1131 :     for (unsigned int j = 0; j < i * 6; j++)
     105        1026 :       _pins_in_rings[i].push_back(k++);
     106             :   //  Given the number of pins and number of fuel Pin rings, the number of subchannels can be
     107             :   //  computed as follows:
     108             :   unsigned int chancount = 0.0;
     109         153 :   for (unsigned int j = 0; j < _n_rings - 1; j++)
     110         105 :     chancount += j * 6;
     111          48 :   _n_channels = chancount + _n_assemblies - 1 + (_n_rings - 1) * 6 + 6;
     112             : 
     113             :   // Defining the array for axial resistances
     114          48 :   _k_grid.resize(_n_channels, std::vector<Real>(_n_cells + 1));
     115             : 
     116             :   /// Re-sizing the object lists with the right number of channels
     117          48 :   _chan_to_pin_map.resize(_n_channels);
     118          48 :   _subch_type.resize(_n_channels);
     119          48 :   _n_gaps = _n_channels + _n_assemblies - 1; /// initial assignment
     120          48 :   _gap_to_chan_map.resize(_n_gaps);
     121          48 :   gap_fill.resize(_n_gaps);
     122          48 :   _chan_to_gap_map.resize(_n_channels);
     123          48 :   _gap_pairs_sf.resize(_n_channels);
     124          48 :   _chan_pairs_sf.resize(_n_channels);
     125          48 :   _gij_map.resize(_n_gaps);
     126          48 :   _sign_id_crossflow_map.resize(_n_channels);
     127          48 :   _gap_to_pin_map.resize(_n_gaps);
     128          48 :   _gap_type.resize(_n_gaps);
     129          48 :   _subchannel_position.resize(_n_channels);
     130             : 
     131        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     132             :   {
     133        2340 :     _chan_to_pin_map[i].reserve(3);
     134        2340 :     _chan_to_gap_map[i].reserve(3);
     135        2340 :     _sign_id_crossflow_map[i].reserve(3);
     136        2340 :     _subchannel_position[i].reserve(3);
     137        9360 :     for (unsigned int j = 0; j < 3; j++)
     138             :     {
     139        7020 :       _sign_id_crossflow_map.at(i).push_back(positive_flow);
     140        7020 :       _subchannel_position.at(i).push_back(0.0);
     141             :     }
     142             :   } // i
     143             : 
     144             :   // create the subchannels
     145             :   k = 0; // initialize the subchannel counter index
     146             :   kgap = 0;
     147             :   // for each ring we trace the subchannels by pairing up to neighbor pins and looking for the third
     148             :   // Pin at inner or outer ring compared to the current ring.
     149         153 :   for (unsigned int i = 1; i < _n_rings; i++)
     150             :   {
     151             :     // find the closest Pin at back ring
     152        1131 :     for (unsigned int j = 0; j < _pins_in_rings[i].size(); j++)
     153             :     {
     154        1026 :       if (j == _pins_in_rings[i].size() - 1)
     155             :       {
     156         105 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     157         105 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][0]);
     158         105 :         avg_coor_x =
     159         105 :             0.5 * (_pin_position[_pins_in_rings[i][j]](0) + _pin_position[_pins_in_rings[i][0]](0));
     160         105 :         avg_coor_y =
     161         105 :             0.5 * (_pin_position[_pins_in_rings[i][j]](1) + _pin_position[_pins_in_rings[i][0]](1));
     162         105 :         _gap_to_pin_map[kgap].first = _pins_in_rings[i][0];
     163         105 :         _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
     164         105 :         _gap_type[kgap] = EChannelType::CENTER;
     165         105 :         kgap = kgap + 1;
     166             :       }
     167             :       else
     168             :       {
     169         921 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     170         921 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j + 1]);
     171         921 :         avg_coor_x = 0.5 * (_pin_position[_pins_in_rings[i][j]](0) +
     172         921 :                             _pin_position[_pins_in_rings[i][j + 1]](0));
     173         921 :         avg_coor_y = 0.5 * (_pin_position[_pins_in_rings[i][j]](1) +
     174         921 :                             _pin_position[_pins_in_rings[i][j + 1]](1));
     175         921 :         _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
     176         921 :         _gap_to_pin_map[kgap].second = _pins_in_rings[i][j + 1];
     177         921 :         _gap_type[kgap] = EChannelType::CENTER;
     178         921 :         kgap = kgap + 1;
     179             :       }
     180             : 
     181             :       dist0 = 1.0e+5;
     182             : 
     183        1026 :       _chan_to_pin_map[k].push_back(_pins_in_rings[i - 1][0]);
     184             :       unsigned int l0 = 0;
     185             : 
     186        6714 :       for (unsigned int l = 0; l < _pins_in_rings[i - 1].size(); l++)
     187             :       {
     188        5688 :         dist = std::sqrt(pow(_pin_position[_pins_in_rings[i - 1][l]](0) - avg_coor_x, 2) +
     189        5688 :                          pow(_pin_position[_pins_in_rings[i - 1][l]](1) - avg_coor_y, 2));
     190             : 
     191        5688 :         if (dist < dist0)
     192             :         {
     193        2508 :           _chan_to_pin_map[k][2] = _pins_in_rings[i - 1][l];
     194             :           l0 = l;
     195             :           dist0 = dist;
     196             :         } // if
     197             :       } // l
     198             : 
     199        1026 :       _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
     200        1026 :       _gap_to_pin_map[kgap].second = _pins_in_rings[i - 1][l0];
     201        1026 :       _gap_type[kgap] = EChannelType::CENTER;
     202        1026 :       kgap = kgap + 1;
     203        1026 :       _subch_type[k] = EChannelType::CENTER;
     204        1026 :       k = k + 1;
     205             : 
     206             :     } // for j
     207             : 
     208             :     // find the closest Pin at front ring
     209             : 
     210        1131 :     for (unsigned int j = 0; j < _pins_in_rings[i].size(); j++)
     211             :     {
     212        1026 :       if (j == _pins_in_rings[i].size() - 1)
     213             :       {
     214         105 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     215         105 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][0]);
     216         105 :         avg_coor_x =
     217         105 :             0.5 * (_pin_position[_pins_in_rings[i][j]](0) + _pin_position[_pins_in_rings[i][0]](0));
     218         105 :         avg_coor_y =
     219         105 :             0.5 * (_pin_position[_pins_in_rings[i][j]](1) + _pin_position[_pins_in_rings[i][0]](1));
     220             :       }
     221             :       else
     222             :       {
     223         921 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     224         921 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i][j + 1]);
     225         921 :         avg_coor_x = 0.5 * (_pin_position[_pins_in_rings[i][j]](0) +
     226         921 :                             _pin_position[_pins_in_rings[i][j + 1]](0));
     227         921 :         avg_coor_y = 0.5 * (_pin_position[_pins_in_rings[i][j]](1) +
     228         921 :                             _pin_position[_pins_in_rings[i][j + 1]](1));
     229             :       }
     230             : 
     231             :       // if the outermost ring, set the edge subchannels first... then the corner subchannels
     232        1026 :       if (i == _n_rings - 1)
     233             :       {
     234             :         // add  edges
     235         630 :         _subch_type[k] = EChannelType::EDGE; // an edge subchannel is created
     236         630 :         _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
     237         630 :         _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
     238         630 :         _gap_type[kgap] = EChannelType::EDGE;
     239         630 :         _chan_to_gap_map[k].push_back(kgap);
     240         630 :         kgap = kgap + 1;
     241         630 :         k = k + 1;
     242             : 
     243         630 :         if (j % i == 0)
     244             :         {
     245             :           // generate a corner subchannel, generate the additional gap and fix chan_to_gap_map
     246         288 :           _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
     247         288 :           _gap_to_pin_map[kgap].second = _pins_in_rings[i][j];
     248         288 :           _gap_type[kgap] = EChannelType::CORNER;
     249             : 
     250             :           // corner subchannel
     251         288 :           _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     252             :           // corner subchannel-dummy added to hinder array size violations
     253         288 :           _chan_to_pin_map[k].push_back(_pins_in_rings[i][j]);
     254         288 :           _chan_to_gap_map[k].push_back(kgap - 1);
     255         288 :           _chan_to_gap_map[k].push_back(kgap);
     256         288 :           _subch_type[k] = EChannelType::CORNER;
     257             : 
     258         288 :           kgap = kgap + 1;
     259         288 :           k = k + 1;
     260             :         }
     261             :         // if not the outer most ring
     262             :       }
     263             :       else
     264             :       {
     265             :         dist0 = 1.0e+5;
     266             :         unsigned int l0 = 0;
     267         396 :         _chan_to_pin_map[k].push_back(_pins_in_rings[i + 1][0]);
     268        5796 :         for (unsigned int l = 0; l < _pins_in_rings[i + 1].size(); l++)
     269             :         {
     270        5400 :           dist = std::sqrt(pow(_pin_position[_pins_in_rings[i + 1][l]](0) - avg_coor_x, 2) +
     271        5400 :                            pow(_pin_position[_pins_in_rings[i + 1][l]](1) - avg_coor_y, 2));
     272        5400 :           if (dist < dist0)
     273             :           {
     274        1896 :             _chan_to_pin_map[k][2] = _pins_in_rings[i + 1][l];
     275             :             dist0 = dist;
     276             :             l0 = l;
     277             :           } // if
     278             :         } // l
     279             : 
     280         396 :         _gap_to_pin_map[kgap].first = _pins_in_rings[i][j];
     281         396 :         _gap_to_pin_map[kgap].second = _pins_in_rings[i + 1][l0];
     282         396 :         _gap_type[kgap] = EChannelType::CENTER;
     283         396 :         kgap = kgap + 1;
     284         396 :         _subch_type[k] = EChannelType::CENTER;
     285         396 :         k = k + 1;
     286             :       } // if
     287             :     } // for j
     288             :   } // for i
     289             : 
     290             :   // find the _gap_to_chan_map and _chan_to_gap_map using the gap_to_rod and subchannel_to_rod_maps
     291             : 
     292        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     293             :   {
     294        2340 :     if (_subch_type[i] == EChannelType::CENTER)
     295             :     {
     296      112986 :       for (unsigned int j = 0; j < _n_gaps; j++)
     297             :       {
     298      111564 :         if (_gap_type[j] == EChannelType::CENTER)
     299             :         {
     300       86688 :           if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
     301       83052 :                (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second)) ||
     302       81792 :               ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
     303        3348 :                (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first)))
     304             :           {
     305        1422 :             _chan_to_gap_map[i].push_back(j);
     306             :           }
     307             : 
     308       86688 :           if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
     309       83052 :                (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].second)) ||
     310       81630 :               ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
     311        3348 :                (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].first)))
     312             :           {
     313        1422 :             _chan_to_gap_map[i].push_back(j);
     314             :           }
     315             : 
     316       86688 :           if (((_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first) &&
     317       83052 :                (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].second)) ||
     318       82422 :               ((_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second) &&
     319        3348 :                (_chan_to_pin_map[i][2] == _gap_to_pin_map[j].first)))
     320             :           {
     321        1422 :             _chan_to_gap_map[i].push_back(j);
     322             :           }
     323             :         }
     324             :       } // for j
     325             :     }
     326         918 :     else if (_subch_type[i] == EChannelType::EDGE)
     327             :     {
     328       47178 :       for (unsigned int j = 0; j < _n_gaps; j++)
     329             :       {
     330       46548 :         if (_gap_type[j] == EChannelType::CENTER)
     331             :         {
     332       35496 :           if (((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].first) &&
     333       34236 :                (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].second)) ||
     334       33654 :               ((_chan_to_pin_map[i][0] == _gap_to_pin_map[j].second) &&
     335         972 :                (_chan_to_pin_map[i][1] == _gap_to_pin_map[j].first)))
     336             :           {
     337         630 :             _chan_to_gap_map[i].push_back(j);
     338             :           }
     339             :         }
     340             :       }
     341             : 
     342             :       icorner = 0;
     343       29997 :       for (unsigned int k = 0; k < _n_channels; k++)
     344             :       {
     345       29655 :         if (_subch_type[k] == EChannelType::CORNER &&
     346        3060 :             _chan_to_pin_map[i][1] == _chan_to_pin_map[k][0])
     347             :         {
     348         288 :           _chan_to_gap_map[i].push_back(_chan_to_gap_map[k][1]);
     349             :           icorner = 1;
     350             :           break;
     351             :         } // if
     352             :       } // for
     353             : 
     354       29997 :       for (unsigned int k = 0; k < _n_channels; k++)
     355             :       {
     356       29655 :         if (_subch_type[k] == EChannelType::CORNER &&
     357        3060 :             _chan_to_pin_map[i][0] == _chan_to_pin_map[k][0])
     358             :         {
     359         288 :           _chan_to_gap_map[i].push_back(_chan_to_gap_map[k][1] + 1);
     360             :           icorner = 1;
     361             :           break;
     362             :         }
     363             :       }
     364             : 
     365         342 :       if (icorner == 0)
     366             :       {
     367          54 :         _chan_to_gap_map[i].push_back(_chan_to_gap_map[i][0] + 1);
     368             :       }
     369             :     }
     370             :   }
     371             : 
     372             :   // find gap_to_chan_map pair
     373             : 
     374        3414 :   for (unsigned int j = 0; j < _n_gaps; j++)
     375             :   {
     376      181674 :     for (unsigned int i = 0; i < _n_channels; i++)
     377             :     {
     378      178308 :       if (_subch_type[i] == EChannelType::CENTER || _subch_type[i] == EChannelType::EDGE)
     379             :       {
     380      158112 :         if ((j == _chan_to_gap_map[i][0]) || (j == _chan_to_gap_map[i][1]) ||
     381      154008 :             (j == _chan_to_gap_map[i][2]))
     382             :         {
     383        6156 :           if (_gap_to_chan_map[j].first == 0 && gap_fill[j].first == 0)
     384             :           {
     385        3318 :             _gap_to_chan_map[j].first = i;
     386        3318 :             gap_fill[j].first = 1;
     387             :           }
     388        2838 :           else if (_gap_to_chan_map[j].second == 0 && gap_fill[j].second == 0)
     389             :           {
     390        2838 :             _gap_to_chan_map[j].second = i;
     391        2838 :             gap_fill[j].second = 1;
     392             :           }
     393             :           else
     394             :           {
     395             :           }
     396             :         }
     397             :       }
     398       20196 :       else if (_subch_type[i] == EChannelType::CORNER)
     399             :       {
     400       20196 :         if ((j == _chan_to_gap_map[i][0]) || (j == _chan_to_gap_map[i][1]))
     401             :         {
     402         576 :           if (_gap_to_chan_map[j].first == 0 && gap_fill[j].first == 0)
     403             :           {
     404          48 :             _gap_to_chan_map[j].first = i;
     405          48 :             gap_fill[j].first = 1;
     406             :           }
     407         528 :           else if (_gap_to_chan_map[j].second == 0 && gap_fill[j].second == 0)
     408             :           {
     409         528 :             _gap_to_chan_map[j].second = i;
     410         528 :             gap_fill[j].second = 1;
     411             :           }
     412             :           else
     413             :           {
     414             :           }
     415             :         }
     416             :       }
     417             :     } // i
     418             :   } // j
     419             : 
     420        2388 :   for (unsigned int k = 0; k < _n_channels; k++)
     421             :   {
     422        2340 :     if (_subch_type[k] == EChannelType::EDGE)
     423             :     {
     424         630 :       _gap_pairs_sf[k].first = _chan_to_gap_map[k][0];
     425         630 :       _gap_pairs_sf[k].second = _chan_to_gap_map[k][2];
     426             :       auto k1 = _gap_pairs_sf[k].first;
     427             :       auto k2 = _gap_pairs_sf[k].second;
     428         630 :       if (_gap_to_chan_map[k1].first == k)
     429             :       {
     430         288 :         _chan_pairs_sf[k].first = _gap_to_chan_map[k1].second;
     431             :       }
     432             :       else
     433             :       {
     434         342 :         _chan_pairs_sf[k].first = _gap_to_chan_map[k1].first;
     435             :       }
     436             : 
     437         630 :       if (_gap_to_chan_map[k2].first == k)
     438             :       {
     439         582 :         _chan_pairs_sf[k].second = _gap_to_chan_map[k2].second;
     440             :       }
     441             :       else
     442             :       {
     443          48 :         _chan_pairs_sf[k].second = _gap_to_chan_map[k2].first;
     444             :       }
     445             :     }
     446        1710 :     else if (_subch_type[k] == EChannelType::CORNER)
     447             :     {
     448         288 :       _gap_pairs_sf[k].first = _chan_to_gap_map[k][1];
     449         288 :       _gap_pairs_sf[k].second = _chan_to_gap_map[k][0];
     450             : 
     451             :       auto k1 = _gap_pairs_sf[k].first;
     452             :       auto k2 = _gap_pairs_sf[k].second;
     453             : 
     454         288 :       if (_gap_to_chan_map[k1].first == k)
     455             :       {
     456          48 :         _chan_pairs_sf[k].first = _gap_to_chan_map[k1].second;
     457             :       }
     458             :       else
     459             :       {
     460         240 :         _chan_pairs_sf[k].first = _gap_to_chan_map[k1].first;
     461             :       }
     462             : 
     463         288 :       if (_gap_to_chan_map[k2].first == k)
     464             :       {
     465           0 :         _chan_pairs_sf[k].second = _gap_to_chan_map[k2].second;
     466             :       }
     467             :       else
     468             :       {
     469         288 :         _chan_pairs_sf[k].second = _gap_to_chan_map[k2].first;
     470             :       }
     471             :     }
     472             :   }
     473             : 
     474             :   // set the _gij_map
     475             : 
     476        3414 :   for (unsigned int j = 0; j < _n_gaps; j++)
     477             :   {
     478        3366 :     if (_gap_type[j] == EChannelType::CENTER)
     479             :     {
     480        2448 :       _gij_map[j] = _assembly_pitch - _flat_to_flat;
     481             :     }
     482         918 :     else if (_gap_type[j] == EChannelType::EDGE || _gap_type[j] == EChannelType::CORNER)
     483             :     {
     484         918 :       _gij_map[j] = _duct_to_pin_gap;
     485             :     }
     486             :   }
     487        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     488             :   {
     489        2340 :     if (_subch_type[i] == EChannelType::CENTER || _subch_type[i] == EChannelType::EDGE)
     490             :     {
     491        8208 :       for (unsigned int k = 0; k < 3; k++)
     492             :       {
     493      480492 :         for (unsigned int j = 0; j < _n_gaps; j++)
     494             :         {
     495      474336 :           if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].first)
     496             :           {
     497        3318 :             if (i > _gap_to_chan_map[j].second)
     498             :             {
     499           0 :               _sign_id_crossflow_map[i][k] = negative_flow;
     500             :             }
     501             :             else
     502             :             {
     503        3318 :               _sign_id_crossflow_map[i][k] = positive_flow;
     504             :             }
     505             :           }
     506      471018 :           else if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].second)
     507             :           {
     508        2838 :             if (i > _gap_to_chan_map[j].first)
     509             :             {
     510        2838 :               _sign_id_crossflow_map[i][k] = negative_flow;
     511             :             }
     512             :             else
     513             :             {
     514           0 :               _sign_id_crossflow_map[i][k] = positive_flow;
     515             :             }
     516             :           }
     517             :         } // j
     518             :       } // k
     519             :     }
     520         288 :     else if (_subch_type[i] == EChannelType::CORNER)
     521             :     {
     522         864 :       for (unsigned int k = 0; k < 2; k++)
     523             :       {
     524       40968 :         for (unsigned int j = 0; j < _n_gaps; j++)
     525             :         {
     526       40392 :           if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].first)
     527             :           {
     528          48 :             if (i > _gap_to_chan_map[j].second)
     529             :             {
     530           0 :               _sign_id_crossflow_map[i][k] = negative_flow;
     531             :             }
     532             :             else
     533             :             {
     534          48 :               _sign_id_crossflow_map[i][k] = positive_flow;
     535             :             }
     536             :           }
     537       40344 :           else if (_chan_to_gap_map[i][k] == j && i == _gap_to_chan_map[j].second)
     538             :           {
     539         528 :             if (i > _gap_to_chan_map[j].first)
     540             :             {
     541         528 :               _sign_id_crossflow_map[i][k] = negative_flow;
     542             :             }
     543             :             else
     544             :             {
     545           0 :               _sign_id_crossflow_map[i][k] = positive_flow;
     546             :             }
     547             :           }
     548             :         } // j
     549             :       } // k
     550             :     } // subch_type =2
     551             :   } // i
     552             : 
     553             :   // set the subchannel positions
     554        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     555             :   {
     556        2340 :     if (_subch_type[i] == EChannelType::CENTER)
     557             :     {
     558        1422 :       _subchannel_position[i][0] =
     559        1422 :           (_pin_position[_chan_to_pin_map[i][0]](0) + _pin_position[_chan_to_pin_map[i][1]](0) +
     560        1422 :            _pin_position[_chan_to_pin_map[i][2]](0)) /
     561             :           3.0;
     562        1422 :       _subchannel_position[i][1] =
     563        1422 :           (_pin_position[_chan_to_pin_map[i][0]](1) + _pin_position[_chan_to_pin_map[i][1]](1) +
     564        1422 :            _pin_position[_chan_to_pin_map[i][2]](1)) /
     565             :           3.0;
     566             :     }
     567         918 :     else if (_subch_type[i] == EChannelType::EDGE)
     568             :     {
     569       32922 :       for (unsigned int j = 0; j < _n_channels; j++)
     570             :       {
     571       32292 :         if (_subch_type[j] == EChannelType::CENTER &&
     572       19980 :             ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][0] &&
     573         630 :               _chan_to_pin_map[i][1] == _chan_to_pin_map[j][1]) ||
     574       19350 :              (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][1] &&
     575         630 :               _chan_to_pin_map[i][1] == _chan_to_pin_map[j][0])))
     576             :         {
     577         630 :           x0 = _pin_position[_chan_to_pin_map[j][2]](0);
     578         630 :           y0 = _pin_position[_chan_to_pin_map[j][2]](1);
     579             :         }
     580       31662 :         else if (_subch_type[j] == EChannelType::CENTER &&
     581       19350 :                  ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][0] &&
     582           0 :                    _chan_to_pin_map[i][1] == _chan_to_pin_map[j][2]) ||
     583       19350 :                   (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][2] &&
     584         342 :                    _chan_to_pin_map[i][1] == _chan_to_pin_map[j][0])))
     585             :         {
     586           0 :           x0 = _pin_position[_chan_to_pin_map[j][1]](0);
     587           0 :           y0 = _pin_position[_chan_to_pin_map[j][1]](1);
     588             :         }
     589       31662 :         else if (_subch_type[j] == EChannelType::CENTER &&
     590       19350 :                  ((_chan_to_pin_map[i][0] == _chan_to_pin_map[j][1] &&
     591         630 :                    _chan_to_pin_map[i][1] == _chan_to_pin_map[j][2]) ||
     592       19350 :                   (_chan_to_pin_map[i][0] == _chan_to_pin_map[j][2] &&
     593         342 :                    _chan_to_pin_map[i][1] == _chan_to_pin_map[j][1])))
     594             :         {
     595           0 :           x0 = _pin_position[_chan_to_pin_map[j][0]](0);
     596           0 :           y0 = _pin_position[_chan_to_pin_map[j][0]](1);
     597             :         }
     598       32292 :         x1 = 0.5 *
     599       32292 :              (_pin_position[_chan_to_pin_map[i][0]](0) + _pin_position[_chan_to_pin_map[i][1]](0));
     600       32292 :         y1 = 0.5 *
     601       32292 :              (_pin_position[_chan_to_pin_map[i][0]](1) + _pin_position[_chan_to_pin_map[i][1]](1));
     602       32292 :         if (_tight_side_bypass)
     603        3024 :           a1 = _flat_to_flat * std::tan(libMesh::pi / 6.0) / 2.0 + _duct_to_pin_gap / 2.0;
     604             :         else
     605       29268 :           a1 = _flat_to_flat / 2.0 + _duct_to_pin_gap / 2.0;
     606       32292 :         a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
     607       32292 :         _subchannel_position[i][0] = (a2 * x1 - a1 * x0) / (a2 - a1);
     608       32292 :         _subchannel_position[i][1] = (a2 * y1 - a1 * y0) / (a2 - a1);
     609             :       } // j
     610             :     }
     611         288 :     else if (_subch_type[i] == EChannelType::CORNER)
     612             :     {
     613         288 :       x0 = _pin_position[0](0);
     614         288 :       y0 = _pin_position[0](1);
     615         288 :       x1 = _pin_position[_chan_to_pin_map[i][0]](0);
     616         288 :       y1 = _pin_position[_chan_to_pin_map[i][0]](1);
     617         288 :       a1 = _flat_to_flat / 2.0 + _duct_to_pin_gap / 2.0;
     618         288 :       a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
     619         288 :       _subchannel_position[i][0] = (a2 * x1 - a1 * x0) / (a2 - a1);
     620         288 :       _subchannel_position[i][1] = (a2 * y1 - a1 * y0) / (a2 - a1);
     621             :     }
     622             :   } // i
     623             :   // Reduce reserved memory in the channel-to-gap map.
     624        2388 :   for (auto & gap : _chan_to_gap_map)
     625             :   {
     626             :     gap.shrink_to_fit();
     627             :   }
     628          48 : }
     629             : 
     630             : std::unique_ptr<MeshBase>
     631          48 : SCMTriInterWrapperMeshGenerator::generate()
     632             : {
     633          48 :   auto mesh_base = buildMeshBaseObject();
     634             : 
     635             :   BoundaryInfo & boundary_info = mesh_base->get_boundary_info();
     636          48 :   mesh_base->set_spatial_dimension(3);
     637          48 :   mesh_base->reserve_elem(_n_cells * _n_channels);
     638          48 :   mesh_base->reserve_nodes((_n_cells + 1) * _n_channels);
     639          48 :   _nodes.resize(_n_channels);
     640             :   // Add the points for the give x,y subchannel positions.  The grid is hexagonal.
     641             :   //  The grid along
     642             :   // z is irregular to account for Pin spacers.  Store pointers in the _nodes
     643             :   // array so we can keep track of which points are in which channels.
     644             :   unsigned int node_id = 0;
     645        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     646             :   {
     647        2340 :     _nodes[i].reserve(_n_cells + 1);
     648       56160 :     for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
     649             :     {
     650       53820 :       _nodes[i].push_back(mesh_base->add_point(
     651      107640 :           Point(_subchannel_position[i][0], _subchannel_position[i][1], _z_grid[iz]), node_id++));
     652             :     }
     653             :   }
     654             : 
     655             :   // Add the elements which in this case are 2-node edges that link each
     656             :   // subchannel's nodes vertically.
     657             :   unsigned int elem_id = 0;
     658        2388 :   for (unsigned int i = 0; i < _n_channels; i++)
     659             :   {
     660       53820 :     for (unsigned int iz = 0; iz < _n_cells; iz++)
     661             :     {
     662       51480 :       Elem * elem = new Edge2;
     663       51480 :       elem->set_id(elem_id++);
     664       51480 :       elem = mesh_base->add_elem(elem);
     665       51480 :       const int indx1 = (_n_cells + 1) * i + iz;
     666       51480 :       const int indx2 = (_n_cells + 1) * i + (iz + 1);
     667       51480 :       elem->set_node(0, mesh_base->node_ptr(indx1));
     668       51480 :       elem->set_node(1, mesh_base->node_ptr(indx2));
     669             : 
     670       51480 :       if (iz == 0)
     671        2340 :         boundary_info.add_side(elem, 0, 0);
     672       51480 :       if (iz == _n_cells - 1)
     673        2340 :         boundary_info.add_side(elem, 1, 1);
     674             :     }
     675             :   }
     676          48 :   boundary_info.sideset_name(0) = "inlet";
     677          48 :   boundary_info.sideset_name(1) = "outlet";
     678          48 :   boundary_info.nodeset_name(0) = "inlet";
     679          48 :   boundary_info.nodeset_name(1) = "outlet";
     680             : 
     681          48 :   mesh_base->prepare_for_use();
     682             : 
     683             :   // move the meta data into TriInterWrapperMesh
     684          48 :   auto & sch_mesh = static_cast<TriInterWrapperMesh &>(*_mesh);
     685          48 :   sch_mesh._unheated_length_entry = _unheated_length_entry;
     686          48 :   sch_mesh._heated_length = _heated_length;
     687          48 :   sch_mesh._unheated_length_exit = _unheated_length_exit;
     688          48 :   sch_mesh._z_grid = _z_grid;
     689          48 :   sch_mesh._k_grid = _k_grid;
     690          48 :   sch_mesh._kij = _kij;
     691          48 :   sch_mesh._assembly_pitch = _assembly_pitch;
     692          48 :   sch_mesh._n_cells = _n_cells;
     693          48 :   sch_mesh._n_rings = _n_rings;
     694          48 :   sch_mesh._n_channels = _n_channels;
     695          48 :   sch_mesh._flat_to_flat = _flat_to_flat;
     696          48 :   sch_mesh._duct_to_pin_gap = _duct_to_pin_gap;
     697          48 :   sch_mesh._nodes = _nodes;
     698          48 :   sch_mesh._gap_to_chan_map = _gap_to_chan_map;
     699          48 :   sch_mesh._gap_to_pin_map = _gap_to_pin_map;
     700          48 :   sch_mesh._chan_to_gap_map = _chan_to_gap_map;
     701          48 :   sch_mesh._sign_id_crossflow_map = _sign_id_crossflow_map;
     702          48 :   sch_mesh._gij_map = _gij_map;
     703          48 :   sch_mesh._subchannel_position = _subchannel_position;
     704          48 :   sch_mesh._pin_position = _pin_position;
     705          48 :   sch_mesh._pins_in_rings = _pins_in_rings;
     706          48 :   sch_mesh._chan_to_pin_map = _chan_to_pin_map;
     707          48 :   sch_mesh._n_assemblies = _n_assemblies;
     708          48 :   sch_mesh._n_gaps = _n_gaps;
     709          48 :   sch_mesh._subch_type = _subch_type;
     710          48 :   sch_mesh._gap_type = _gap_type;
     711          48 :   sch_mesh._gap_pairs_sf = _gap_pairs_sf;
     712          48 :   sch_mesh._chan_pairs_sf = _chan_pairs_sf;
     713          48 :   sch_mesh._tight_side_bypass = _tight_side_bypass;
     714             : 
     715             :   // Overloading assembly sides with flat_to_flat distance
     716          48 :   sch_mesh._assembly_side_x = _flat_to_flat;
     717          48 :   sch_mesh._assembly_side_y = _flat_to_flat;
     718             : 
     719          48 :   return mesh_base;
     720           0 : }

Generated by: LCOV version 1.14