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  _n_elems(moose_object->parameters().get<std::vector<unsigned int>>("n_elems")),
41  _n_elem(std::accumulate(_n_elems.begin(), _n_elems.end(), 0)),
42  _n_sections(_lengths.size()),
43  _section_end(_n_sections),
44  _x_centers(_n_elem),
45  _R(computeDirectionTransformationTensor(_dir)),
46  _Rx(computeXRotationTransformationTensor(_rotation)),
47  _R_inv(_R.inverse()),
48  _Rx_inv(_Rx.inverse()),
49  _moose_object_name_dlsi(moose_object->name())
50 {
51  std::partial_sum(_lengths.begin(), _lengths.end(), _section_end.begin());
52 
53  if (_lengths.size() != _n_elems.size())
54  mooseError("The parameters 'length' and 'n_elems' must have the same number of entries.");
55 
56  // Compute the axial coordinates of the centers of each element
57  unsigned int k_section_begin = 0;
58  Real x_begin = 0.0;
59  for (unsigned int j = 0; j < _n_sections; j++)
60  {
61  const Real dx = _lengths[j] / _n_elems[j];
62  for (unsigned int i = 0; i < _n_elems[j]; i++)
63  {
64  const unsigned int k = k_section_begin + i;
65  _x_centers[k] = x_begin + 0.5 * dx;
66  x_begin += dx;
67  }
68  k_section_begin += _n_elems[j];
69  }
70 }
71 
74 {
75  if (!MooseUtils::absoluteFuzzyEqual(dir_unnormalized.norm(), 0.0))
76  return dir_unnormalized / dir_unnormalized.norm();
77  else
78  mooseError("The parameter 'orientation' must not be the zero vector.");
79 }
80 
83 {
84  if (MooseUtils::absoluteFuzzyEqual(dir.norm(), 0.0))
85  mooseError("The direction vector must not be the zero vector.");
86 
87  const auto dir_normalized = dir / dir.norm();
88  const Real theta = acos(dir_normalized(2));
89  const Real aphi = atan2(dir_normalized(1), dir_normalized(0));
90  return RealTensorValue(
91  RealVectorValue(cos(aphi) * sin(theta), -sin(aphi), -cos(aphi) * cos(theta)),
92  RealVectorValue(sin(aphi) * sin(theta), cos(aphi), -sin(aphi) * cos(theta)),
93  RealVectorValue(cos(theta), 0.0, sin(theta)));
94 }
95 
98 {
99  const Real rotation_rad = M_PI * rotation / 180.;
100  const RealVectorValue Rx_x(1., 0., 0.);
101  const RealVectorValue Rx_y(0., cos(rotation_rad), -sin(rotation_rad));
102  const RealVectorValue Rx_z(0., sin(rotation_rad), cos(rotation_rad));
103  return RealTensorValue(Rx_x, Rx_y, Rx_z);
104 }
105 
106 Real
108 {
109  const Real ax_coord = _dir * (p - _position);
110  if (MooseUtils::absoluteFuzzyLessThan(ax_coord, 0.0) ||
113  ": The point ",
114  p,
115  " has an invalid axial coordinate (",
116  ax_coord,
117  "). Valid axial coordinates are in the range (0,",
118  _length,
119  ").");
120  else
121  return ax_coord;
122 }
123 
124 Real
126 {
127  const RealVectorValue v = (p - _position);
128  return v.cross(_dir).norm();
129 }
130 
131 unsigned int
133 {
134  const Real axial_coordinate = computeAxialCoordinate(p);
135  for (unsigned int i = 0; i < _n_sections; ++i)
136  if (MooseUtils::absoluteFuzzyLessEqual(axial_coordinate, _section_end[i]))
137  return i;
138 
139  mooseError("No axial section index was found.");
140 }
141 
142 unsigned int
144 {
145  const Real axial_coordinate = computeAxialCoordinate(p_center);
146  for (unsigned int i = 0; i < _n_elem; ++i)
147  if (MooseUtils::absoluteFuzzyEqual(axial_coordinate, _x_centers[i]))
148  return i;
149 
150  mooseError("No axial element index was found.");
151 }
152 
153 Point
155  const RealVectorValue & position,
156  const RealTensorValue & R,
157  const RealTensorValue & Rx)
158 {
159  return R * (Rx * p) + position;
160 }
161 
162 Point
164 {
166 }
167 
168 Point
170  const RealVectorValue & position,
171  const RealTensorValue & R_inv,
172  const RealTensorValue & Rx_inv)
173 {
174  return Rx_inv * R_inv * (p - position);
175 }
176 
177 Point
179 {
181 }
182 
183 MooseEnum
185 {
186  MooseEnum axis("x y z");
187  if (THM::areParallelVectors(dir, RealVectorValue(1, 0, 0)))
188  axis = "x";
189  else if (THM::areParallelVectors(dir, RealVectorValue(0, 1, 0)))
190  axis = "y";
191  else if (THM::areParallelVectors(dir, RealVectorValue(0, 0, 1)))
192  axis = "z";
193 
194  return axis;
195 }
196 
197 MooseEnum
199 {
200  return getAlignmentAxis(_dir);
201 }
202 
203 std::vector<Real>
205  const RealVectorValue & position,
206  const RealVectorValue & orientation,
207  const Real & rotation,
208  const std::vector<Real> & lengths,
209  const std::vector<unsigned int> & n_elems)
210 {
211  const auto axis = getAlignmentAxis(orientation);
212 
213  unsigned int d;
214  if (axis == "x")
215  d = 0;
216  else if (axis == "y")
217  d = 1;
218  else if (axis == "z")
219  d = 2;
220  else
221  mooseError("Invalid axis.");
222 
223  const auto R = computeDirectionTransformationTensor(orientation);
224  const auto Rx = computeXRotationTransformationTensor(rotation);
225 
226  const unsigned int n_elems_total = std::accumulate(n_elems.begin(), n_elems.end(), 0);
227  const unsigned int n_sections = lengths.size();
228 
229  unsigned int i_section_start = 0;
230  Real section_start_ref_position = 0.0;
231  std::vector<Real> element_boundary_coordinates(n_elems_total + 1);
232  element_boundary_coordinates[0] =
233  computeRealPointFromReferencePoint(Point(0, 0, 0), position, R, Rx)(d);
234  for (unsigned int j = 0; j < n_sections; ++j)
235  {
236  const Real section_dx = lengths[j] / n_elems[j];
237  for (unsigned int k = 0; k < n_elems[j]; ++k)
238  {
239  const unsigned int i = i_section_start + k + 1;
240  const Real ref_position = section_start_ref_position + section_dx * k;
241  const Point ref_point = Point(ref_position, 0, 0);
242  element_boundary_coordinates[i] =
243  computeRealPointFromReferencePoint(ref_point, position, R, Rx)(d);
244  }
245 
246  section_start_ref_position += lengths[j];
247  i_section_start += n_elems[j];
248  }
249 
250  return element_boundary_coordinates;
251 }
252 
253 std::vector<Real>
255 {
257 }
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
auto norm() const -> decltype(std::norm(Real()))
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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 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:27
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
const std::string name
Definition: Setup.h:20
bool absoluteFuzzyLessThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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.
static const std::string R
Definition: NS.h:162
const std::vector< unsigned int > & _n_elems
Number of elements in each axial section.
const unsigned int _n_elem
Total number of axial elements.
const RealTensorValue _R_inv
Inverse direction transformation tensor.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
Definition: NS.h:84
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.
bool absoluteFuzzyLessEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
unsigned int getAxialElementIndex(const Point &p_center) const
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:130
std::vector< Real > _x_centers
Center axial coordinate of each axial element.
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)
bool absoluteFuzzyGreaterThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)