LCOV - code coverage report
Current view: top level - src/utils - PolygonalMeshGenerationUtils.C (source / functions) Hit Total Coverage
Test: idaholab/moose reactor: #31405 (292dce) with base fef103 Lines: 32 32 100.0 %
Date: 2025-09-04 07:56:24 Functions: 2 2 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 "PolygonalMeshGenerationUtils.h"
      11             : 
      12             : Real
      13        2329 : PolygonalMeshGenerationUtils::dummyTRI6VolCalculator(const std::pair<Real, Real> & azi_pair)
      14             : {
      15             :   // The algorithm is copied from libMesh's face_tri6.C
      16             :   // Original license is LGPL so it can be used here.
      17             :   const Real & azi_1 = azi_pair.first;
      18             :   const Real & azi_2 = azi_pair.second;
      19             : 
      20             :   Point x0 = Point(0.0, 0.0, 0.0), x1 = Point(1.0, 0.0, 0.0),
      21        2329 :         x2 = Point(std::cos(azi_1 + azi_2), std::sin(azi_1 + azi_2), 0.0),
      22        2329 :         x3 = Point(0.5, 0.0, 0.0), x4 = Point(std::cos(azi_1), std::sin(azi_1), 0.0),
      23        2329 :         x5 = Point(std::cos(azi_1 + azi_2) / 2.0, std::sin(azi_1 + azi_2) / 2.0, 0.0);
      24             : 
      25             :   // Construct constant data vectors.
      26             :   // \vec{x}_{\xi}  = \vec{a1}*xi + \vec{b1}*eta + \vec{c1}
      27             :   // \vec{x}_{\eta} = \vec{a2}*xi + \vec{b2}*eta + \vec{c2}
      28             :   Point a1 = 4 * x0 + 4 * x1 - 8 * x3, b1 = 4 * x0 - 4 * x3 + 4 * x4 - 4 * x5,
      29             :         c1 = -3 * x0 - 1 * x1 + 4 * x3, b2 = 4 * x0 + 4 * x2 - 8 * x5,
      30             :         c2 = -3 * x0 - 1 * x2 + 4 * x5;
      31             : 
      32             :   // 7-point rule, exact for quintics.
      33             :   const unsigned int N = 7;
      34             : 
      35             :   // Parameters of the quadrature rule
      36             :   const static Real w1 = Real(31) / 480 + Real(std::sqrt(15.0L) / 2400),
      37             :                     w2 = Real(31) / 480 - Real(std::sqrt(15.0L) / 2400),
      38             :                     q1 = Real(2) / 7 + Real(std::sqrt(15.0L) / 21),
      39             :                     q2 = Real(2) / 7 - Real(std::sqrt(15.0L) / 21);
      40             : 
      41             :   const static Real xi[N] = {Real(1) / 3, q1, q1, 1 - 2 * q1, q2, q2, 1 - 2 * q2};
      42             :   const static Real eta[N] = {Real(1) / 3, q1, 1 - 2 * q1, q1, q2, 1 - 2 * q2, q2};
      43             :   const static Real wts[N] = {Real(9) / 80, w1, w1, w1, w2, w2, w2};
      44             : 
      45             :   // Approximate the area with quadrature
      46             :   Real vol = 0.;
      47       18632 :   for (unsigned int q = 0; q < N; ++q)
      48       16303 :     vol += wts[q] * cross_norm(xi[q] * a1 + eta[q] * b1 + c1, xi[q] * b1 + eta[q] * b2 + c2);
      49             : 
      50        2329 :   return vol;
      51             : }
      52             : 
      53             : Real
      54        2471 : PolygonalMeshGenerationUtils::radiusCorrectionFactor(const std::vector<Real> & azimuthal_list,
      55             :                                                      const bool full_circle,
      56             :                                                      const unsigned int order,
      57             :                                                      const bool is_first_value_vertex)
      58             : {
      59             :   Real tmp_acc = 0.0;
      60             :   Real tmp_acc_azi = 0.0;
      61        2471 :   if (order == 1)
      62             :   {
      63             :     // A vector to collect the azimuthal intervals of all EDGE2 side elements
      64             :     std::vector<Real> azi_interval_list;
      65       53308 :     for (unsigned int i = 1; i < azimuthal_list.size(); i++)
      66       50986 :       azi_interval_list.push_back((azimuthal_list[i] - azimuthal_list[i - 1]) / 180.0 * M_PI);
      67        2322 :     if (full_circle)
      68        2313 :       azi_interval_list.push_back((azimuthal_list.front() + 360.0 - azimuthal_list.back()) / 180.0 *
      69             :                                   M_PI);
      70             :     // summation of triangles S = 0.5 * r * r * Sigma_i [sin (azi_i)]
      71             :     // Circle area S_c = pi * r_0 * r_0
      72             :     // r = sqrt{2 * pi / Sigma_i [sin (azi_i)]} * r_0
      73       55621 :     for (const auto i : index_range(azi_interval_list))
      74             :     {
      75       53299 :       tmp_acc += std::sin(azi_interval_list[i]);
      76       53299 :       tmp_acc_azi += azi_interval_list[i];
      77             :     }
      78        2322 :   }
      79             :   else // order == 2
      80             :   {
      81             :     // A vector to collect the pairs of azimuthal intervals of all EDGE3 side elements
      82             :     // The midpoint divides the interval into two parts, which are stored as first and second of
      83             :     // each pair; the sum of the two parts is the full interval of the EDGE3 element
      84             :     std::vector<std::pair<Real, Real>> azi_interval_list;
      85        2478 :     for (unsigned int i = is_first_value_vertex ? 2 : 3; i < azimuthal_list.size(); i += 2)
      86             :       azi_interval_list.push_back(
      87        2180 :           std::make_pair((azimuthal_list[i - 1] - azimuthal_list[i - 2]) / 180.0 * M_PI,
      88        2180 :                          (azimuthal_list[i] - azimuthal_list[i - 1]) / 180.0 * M_PI));
      89             :     // If it is not a full circle, the first value should always belong to a vertex
      90         149 :     if (full_circle)
      91             :     {
      92         149 :       if (is_first_value_vertex)
      93         132 :         azi_interval_list.push_back(std::make_pair(
      94         132 :             (azimuthal_list.back() - azimuthal_list[azimuthal_list.size() - 2]) / 180.0 * M_PI,
      95         132 :             (azimuthal_list.front() + 360.0 - azimuthal_list.back()) / 180.0 * M_PI));
      96             :       else
      97             :         azi_interval_list.push_back(
      98          17 :             std::make_pair((azimuthal_list.front() + 360.0 - azimuthal_list.back()) / 180.0 * M_PI,
      99          17 :                            (azimuthal_list[1] - azimuthal_list.front()) / 180.0 * M_PI));
     100             :     }
     101             :     // Use the libMesh TRI6 element volume algorithm
     102        2478 :     for (const auto i : index_range(azi_interval_list))
     103             :     {
     104        2329 :       tmp_acc += 2.0 * dummyTRI6VolCalculator(azi_interval_list[i]);
     105        2329 :       tmp_acc_azi += azi_interval_list[i].first + azi_interval_list[i].second;
     106             :     }
     107         149 :   }
     108        2471 :   return std::sqrt(tmp_acc_azi / tmp_acc);
     109             : }

Generated by: LCOV version 1.14