https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DiscreteLineSegmentInterface.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#include "MooseObject.h"
12#include "MooseEnum.h"
13#include "MooseUtils.h"
14#include "Numerics.h"
15
18{
20
21 params.addRequiredParam<Point>("position", "Start position of axis in 3-D space [m]");
22 params.addRequiredParam<RealVectorValue>(
23 "orientation",
24 "Direction of axis from start position to end position (no need to normalize)");
25 params.addParam<Real>("rotation", 0.0, "Angle of rotation about the x-axis [degrees]");
26 params.addRequiredParam<std::vector<Real>>("length", "Length of each axial section [m]");
27 params.addRequiredParam<std::vector<unsigned int>>("n_elems",
28 "Number of elements in each axial section");
29
30 return params;
31}
32
34 : _position(moose_object->parameters().get<Point>("position")),
35 _dir_unnormalized(moose_object->parameters().get<RealVectorValue>("orientation")),
36 _dir(initializeDirectionVector(_dir_unnormalized)),
37 _rotation(moose_object->parameters().get<Real>("rotation")),
38 _lengths(moose_object->parameters().get<std::vector<Real>>("length")),
39 _length(std::accumulate(_lengths.begin(), _lengths.end(), 0.0)),
40 _end_point(_position + _dir * _length),
41 _n_elems(moose_object->parameters().get<std::vector<unsigned int>>("n_elems")),
42 _n_elem(std::accumulate(_n_elems.begin(), _n_elems.end(), 0)),
43 _n_sections(_lengths.size()),
44 _section_end(_n_sections),
45 _x_centers(_n_elem),
46 _R(computeDirectionTransformationTensor(_dir)),
47 _Rx(computeXRotationTransformationTensor(_rotation)),
48 _R_inv(_R.inverse()),
49 _Rx_inv(_Rx.inverse()),
50 _moose_object_name_dlsi(moose_object->name())
51{
52 std::partial_sum(_lengths.begin(), _lengths.end(), _section_end.begin());
53
54 if (_lengths.size() != _n_elems.size())
55 mooseError("The parameters 'length' and 'n_elems' must have the same number of entries.");
56
57 // Compute the axial coordinates of the centers of each element
58 unsigned int k_section_begin = 0;
59 Real x_begin = 0.0;
60 _dx_min = std::numeric_limits<Real>::max();
61 for (unsigned int j = 0; j < _n_sections; j++)
62 {
63 const Real dx = _lengths[j] / _n_elems[j];
64 _dx_min = std::min(dx, _dx_min);
65 for (unsigned int i = 0; i < _n_elems[j]; i++)
66 {
67 const unsigned int k = k_section_begin + i;
68 _x_centers[k] = x_begin + 0.5 * dx;
69 x_begin += dx;
70 }
71 k_section_begin += _n_elems[j];
72 }
73}
74
75RealVectorValue
76DiscreteLineSegmentInterface::initializeDirectionVector(const RealVectorValue & dir_unnormalized)
77{
78 if (!MooseUtils::absoluteFuzzyEqual(dir_unnormalized.norm(), 0.0))
79 return dir_unnormalized / dir_unnormalized.norm();
80 else
81 mooseError("The parameter 'orientation' must not be the zero vector.");
82}
83
84RealTensorValue
86{
87 if (MooseUtils::absoluteFuzzyEqual(dir.norm(), 0.0))
88 mooseError("The direction vector must not be the zero vector.");
89
90 const auto dir_normalized = dir / dir.norm();
91 const Real theta = acos(dir_normalized(2));
92 const Real aphi = atan2(dir_normalized(1), dir_normalized(0));
93 return RealTensorValue(
94 RealVectorValue(cos(aphi) * sin(theta), -sin(aphi), -cos(aphi) * cos(theta)),
95 RealVectorValue(sin(aphi) * sin(theta), cos(aphi), -sin(aphi) * cos(theta)),
96 RealVectorValue(cos(theta), 0.0, sin(theta)));
97}
98
99RealTensorValue
101{
102 const Real rotation_rad = M_PI * rotation / 180.;
103 const RealVectorValue Rx_x(1., 0., 0.);
104 const RealVectorValue Rx_y(0., cos(rotation_rad), -sin(rotation_rad));
105 const RealVectorValue Rx_z(0., sin(rotation_rad), cos(rotation_rad));
106 return RealTensorValue(Rx_x, Rx_y, Rx_z);
107}
108
109Real
111{
112 const Real ax_coord = _dir * (p - _position);
113 if (MooseUtils::absoluteFuzzyLessThan(ax_coord, 0.0) ||
114 MooseUtils::absoluteFuzzyGreaterThan(ax_coord, _length))
116 ": The point ",
117 p,
118 " has an invalid axial coordinate (",
119 ax_coord,
120 "). Valid axial coordinates are in the range (0,",
121 _length,
122 ").");
123 else
124 return ax_coord;
125}
126
127Real
129{
130 const RealVectorValue v = (p - _position);
131 return v.cross(_dir).norm();
132}
133
134unsigned int
136{
137 const Real axial_coordinate = computeAxialCoordinate(p);
138 for (unsigned int i = 0; i < _n_sections; ++i)
139 if (MooseUtils::absoluteFuzzyLessEqual(axial_coordinate, _section_end[i]))
140 return i;
141
142 mooseError("No axial section index was found.");
143}
144
145unsigned int
147{
148 const Real axial_coordinate = computeAxialCoordinate(p_center);
149 for (unsigned int i = 0; i < _n_elem; ++i)
150 if (MooseUtils::absoluteFuzzyEqual(axial_coordinate, _x_centers[i]))
151 return i;
152
153 mooseError("No axial element index was found.");
154}
155
156Point
158 const RealVectorValue & position,
159 const RealTensorValue & R,
160 const RealTensorValue & Rx)
161{
162 return R * (Rx * p) + position;
163}
164
165Point
170
171Point
173 const RealVectorValue & position,
174 const RealTensorValue & R_inv,
175 const RealTensorValue & Rx_inv)
176{
177 return Rx_inv * R_inv * (p - position);
178}
179
180Point
185
188{
189 MooseEnum axis("x y z");
190 if (THM::areParallelVectors(dir, RealVectorValue(1, 0, 0)))
191 axis = "x";
192 else if (THM::areParallelVectors(dir, RealVectorValue(0, 1, 0)))
193 axis = "y";
194 else if (THM::areParallelVectors(dir, RealVectorValue(0, 0, 1)))
195 axis = "z";
196
197 return axis;
198}
199
205
206std::vector<Real>
208 const RealVectorValue & position,
209 const RealVectorValue & orientation,
210 const Real & rotation,
211 const std::vector<Real> & lengths,
212 const std::vector<unsigned int> & n_elems)
213{
214 const auto axis = getAlignmentAxis(orientation);
215
216 unsigned int d;
217 if (axis == "x")
218 d = 0;
219 else if (axis == "y")
220 d = 1;
221 else if (axis == "z")
222 d = 2;
223 else
224 mooseError("Invalid axis.");
225
226 const auto R = computeDirectionTransformationTensor(orientation);
227 const auto Rx = computeXRotationTransformationTensor(rotation);
228
229 const unsigned int n_elems_total = std::accumulate(n_elems.begin(), n_elems.end(), 0);
230 const unsigned int n_sections = lengths.size();
231
232 unsigned int i_section_start = 0;
233 Real section_start_ref_position = 0.0;
234 std::vector<Real> element_boundary_coordinates(n_elems_total + 1);
235 element_boundary_coordinates[0] =
236 computeRealPointFromReferencePoint(Point(0, 0, 0), position, R, Rx)(d);
237 for (unsigned int j = 0; j < n_sections; ++j)
238 {
239 const Real section_dx = lengths[j] / n_elems[j];
240 for (unsigned int k = 0; k < n_elems[j]; ++k)
241 {
242 const unsigned int i = i_section_start + k + 1;
243 const Real ref_position = section_start_ref_position + section_dx * k;
244 const Point ref_point = Point(ref_position, 0, 0);
245 element_boundary_coordinates[i] =
246 computeRealPointFromReferencePoint(ref_point, position, R, Rx)(d);
247 }
248
249 section_start_ref_position += lengths[j];
250 i_section_start += n_elems[j];
251 }
252
253 return element_boundary_coordinates;
254}
255
256std::vector<Real>
const double R
const Real p
const double v
InputParameters emptyInputParameters()
void mooseError(Args &&... args)
const std::string name
Definition Setup.h:21
void ErrorVector unsigned int
const RealTensorValue _Rx_inv
Inverse rotational transformation tensor about x-axis.
unsigned int _n_elem
Total number of axial elements.
const unsigned int _n_sections
Number of axial sections.
std::vector< Real > _section_end
Axial coordinate of the end of each axial section using the line 'position' as the origin.
std::vector< Real > _x_centers
Center axial coordinate of each axial element.
std::vector< unsigned int > _n_elems
Number of elements in each axial section.
Real computeAxialCoordinate(const Point &p) const
const Real & _rotation
Angle of rotation about the x-axis.
unsigned int getAxialElementIndex(const Point &p_center) const
const Point & _position
Start position of axis in 3-D space.
Point computeRealPointFromReferencePoint(const Point &p) const
Computes point in 3-D space from a point in reference space.
const RealTensorValue _R_inv
Inverse direction transformation tensor.
static RealTensorValue computeDirectionTransformationTensor(const RealVectorValue &dir)
Computes the direction transformation tensor.
Real computeRadialCoordinate(const Point &p) const
unsigned int getAxialSectionIndex(const Point &p) const
Point computeReferencePointFromRealPoint(const Point &p) const
Computes point in reference space from a point in 3-D space.
DiscreteLineSegmentInterface(const MooseObject *moose_object)
std::vector< Real > _lengths
Length of each axial section.
const RealTensorValue _R
Direction transformation tensor.
const std::string _moose_object_name_dlsi
Name of the MOOSE object.
std::vector< Real > getElementBoundaryCoordinates() const
Gets the element boundary coordinates for the aligned axis.
static RealTensorValue computeXRotationTransformationTensor(const Real &rotation)
Computes the rotation transformation tensor.
static RealVectorValue initializeDirectionVector(const RealVectorValue &dir_unnormalized)
Computes a normalized direction vector or reports an error if the zero vector is provided.
const RealVectorValue _dir
Normalized direction of axis from start position to end position.
MooseEnum getAlignmentAxis() const
Gets an axis MooseEnum for the axis the component is aligned with.
const RealTensorValue _Rx
Rotational transformation tensor about x-axis.
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
bool areParallelVectors(const RealVectorValue &a, const RealVectorValue &b, const Real &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Tests if two real-valued vectors are parallel within some absolute tolerance.