https://mooseframework.inl.gov
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]");
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 
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 
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 
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 
109 Real
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 
127 Real
129 {
130  const RealVectorValue v = (p - _position);
131  return v.cross(_dir).norm();
132 }
133 
134 unsigned 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 
145 unsigned 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 
156 Point
158  const RealVectorValue & position,
159  const RealTensorValue & R,
160  const RealTensorValue & Rx)
161 {
162  return R * (Rx * p) + position;
163 }
164 
165 Point
167 {
169 }
170 
171 Point
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 
180 Point
182 {
184 }
185 
186 MooseEnum
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 
200 MooseEnum
202 {
203  return getAlignmentAxis(_dir);
204 }
205 
206 std::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 
256 std::vector<Real>
258 {
260 }
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
auto norm() const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
Real computeAxialCoordinate(const Point &p) const
unsigned int getAxialSectionIndex(const Point &p) const
static RealTensorValue computeXRotationTransformationTensor(const Real &rotation)
Computes the rotation transformation tensor.
const double v
const RealTensorValue _Rx_inv
Inverse rotational transformation tensor about x-axis.
std::vector< Real > _lengths
Length of each axial section.
static RealTensorValue computeDirectionTransformationTensor(const RealVectorValue &dir)
Computes the direction transformation tensor.
void inverse(const std::vector< std::vector< Real >> &m, std::vector< std::vector< Real >> &m_inv)
static const std::string axis
Definition: NS.h:28
const double R
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.
Definition: Numerics.C:26
const Real & _rotation
Angle of rotation about the x-axis.
void addRequiredParam(const std::string &name, const std::string &doc_string)
InputParameters emptyInputParameters()
const RealVectorValue _dir
Normalized direction of axis from start position to end position.
TensorValue< Real > RealTensorValue
std::vector< Real > _section_end
Axial coordinate of the end of each axial section using the line &#39;position&#39; as the origin...
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
unsigned int _n_elem
Total number of axial elements.
const std::string name
Definition: Setup.h:21
const unsigned int _n_sections
Number of axial sections.
const Point & _position
Start position of axis in 3-D space.
Real computeRadialCoordinate(const Point &p) const
Point computeReferencePointFromRealPoint(const Point &p) const
Computes point in reference space from a point in 3-D space.
const RealTensorValue _R_inv
Inverse direction transformation tensor.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const RealTensorValue _Rx
Rotational transformation tensor about x-axis.
const RealTensorValue _R
Direction transformation tensor.
MooseEnum getAlignmentAxis() const
Gets an axis MooseEnum for the axis the component is aligned with.
const Real p
unsigned int getAxialElementIndex(const Point &p_center) const
std::vector< unsigned int > _n_elems
Number of elements in each axial section.
const std::string _moose_object_name_dlsi
Name of the MOOSE object.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
DiscreteLineSegmentInterface(const MooseObject *moose_object)
static RealVectorValue initializeDirectionVector(const RealVectorValue &dir_unnormalized)
Computes a normalized direction vector or reports an error if the zero vector is provided.
std::vector< Real > getElementBoundaryCoordinates() const
Gets the element boundary coordinates for the aligned axis.
Point computeRealPointFromReferencePoint(const Point &p) const
Computes point in 3-D space from a point in reference space.
static const std::string k
Definition: NS.h:134
std::vector< Real > _x_centers
Center axial coordinate of each axial element.
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)