https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PolygonalMeshGenerationUtils.C
Go to the documentation of this file.
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
11
12Real
13PolygonalMeshGenerationUtils::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 x2 = Point(std::cos(azi_1 + azi_2), std::sin(azi_1 + azi_2), 0.0),
22 x3 = Point(0.5, 0.0, 0.0), x4 = Point(std::cos(azi_1), std::sin(azi_1), 0.0),
23 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 for (unsigned int q = 0; q < N; ++q)
48 vol += wts[q] * cross_norm(xi[q] * a1 + eta[q] * b1 + c1, xi[q] * b1 + eta[q] * b2 + c2);
49
50 return vol;
51}
52
53Real
54PolygonalMeshGenerationUtils::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 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 for (unsigned int i = 1; i < azimuthal_list.size(); i++)
66 azi_interval_list.push_back((azimuthal_list[i] - azimuthal_list[i - 1]) / 180.0 * M_PI);
67 if (full_circle)
68 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 for (const auto i : index_range(azi_interval_list))
74 {
75 tmp_acc += std::sin(azi_interval_list[i]);
76 tmp_acc_azi += azi_interval_list[i];
77 }
78 }
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 for (unsigned int i = is_first_value_vertex ? 2 : 3; i < azimuthal_list.size(); i += 2)
86 azi_interval_list.push_back(
87 std::make_pair((azimuthal_list[i - 1] - azimuthal_list[i - 2]) / 180.0 * M_PI,
88 (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 if (full_circle)
91 {
92 if (is_first_value_vertex)
93 azi_interval_list.push_back(std::make_pair(
94 (azimuthal_list.back() - azimuthal_list[azimuthal_list.size() - 2]) / 180.0 * M_PI,
95 (azimuthal_list.front() + 360.0 - azimuthal_list.back()) / 180.0 * M_PI));
96 else
97 azi_interval_list.push_back(
98 std::make_pair((azimuthal_list.front() + 360.0 - azimuthal_list.back()) / 180.0 * M_PI,
99 (azimuthal_list[1] - azimuthal_list.front()) / 180.0 * M_PI));
100 }
101 // Use the libMesh TRI6 element volume algorithm
102 for (const auto i : index_range(azi_interval_list))
103 {
104 tmp_acc += 2.0 * dummyTRI6VolCalculator(azi_interval_list[i]);
105 tmp_acc_azi += azi_interval_list[i].first + azi_interval_list[i].second;
106 }
107 }
108 return std::sqrt(tmp_acc_azi / tmp_acc);
109}
Point eta
Point xi
Real dummyTRI6VolCalculator(const std::pair< Real, Real > &azi_pair)
Based on a pair of azimuthal angles, calculates the volume of a TRI6 element with one vertex at the o...
Real radiusCorrectionFactor(const std::vector< Real > &azimuthal_list, const bool full_circle=true, const unsigned int order=1, const bool is_first_value_vertex=true)
Makes radial correction to preserve ring area.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real