https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TransformGenerator.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
10#include "TransformGenerator.h"
11#include "libmesh/mesh_modification.h"
12#include "CastUniquePointer.h"
13
14#include "libmesh/mesh_tools.h"
15
17
20{
21 MooseEnum transforms("TRANSLATE=1 TRANSLATE_CENTER_ORIGIN=2 TRANSLATE_MIN_ORIGIN=3 ROTATE=4 "
22 "SCALE=5 ROTATE_WITH_MATRIX=6 ROTATE_EXT=7");
23
25
26 params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
27 params.addClassDescription("Applies a linear transform to the entire mesh.");
29 "transform",
30 transforms,
31 "The type of transformation to perform (TRANSLATE, TRANSLATE_CENTER_ORIGIN, "
32 "TRANSLATE_MIN_ORIGIN, ROTATE, SCALE, ROTATE_WITH_MATRIX, ROTATE_EXT)");
33 params.addParam<RealVectorValue>(
34 "vector_value",
35 "The value to use for the transformation. When using TRANSLATE or SCALE, the "
36 "xyz coordinates are applied in each direction respectively. When using "
37 "ROTATE, the values are interpreted as the Euler angles phi, theta and psi "
38 "given in degrees. For ROTATE_EXT, an extrinsic rotation is carried out using prescribed "
39 "Euler angles alpha, beta, and gamma in degrees.");
40 params.addParam<RealTensorValue>(
41 "rotation_matrix",
42 "Precomputed extrinsic rotation matrix to be applied to mesh (ROTATE_WITH_MATRIX option).");
43
44 return params;
45}
46
48 : MeshGenerator(parameters),
49 _input(getMesh("input")),
50 _transform(getParam<MooseEnum>("transform"))
51{
52 if ((_transform != "TRANSLATE_CENTER_ORIGIN" && _transform != "TRANSLATE_MIN_ORIGIN" &&
53 _transform != "ROTATE_WITH_MATRIX") &&
54 !isParamValid("vector_value"))
55 paramError("transform",
56 "The parameter 'vector_value' must be supplied with 'transform' = ",
58}
59
60std::unique_ptr<MeshBase>
62{
63 std::unique_ptr<MeshBase> mesh = std::move(_input);
64
65 RealVectorValue vector_value;
66 RealTensorValue rotation_matrix;
67 if (_transform == 2 || _transform == 3)
68 {
69 const auto bbox = MeshTools::create_bounding_box(*mesh);
70 if (_transform == 2)
71 vector_value = -0.5 * (bbox.max() + bbox.min());
72 else
73 vector_value = -bbox.min();
74 }
75 else if (_transform == 6)
76 rotation_matrix = getParam<RealTensorValue>("rotation_matrix");
77 else
78 vector_value = getParam<RealVectorValue>("vector_value");
79
80 // Any non-identity transform is going to invalidate any existing
81 // point locator
82 mesh->clear_point_locator();
83
84 switch (_transform)
85 {
86 case 1:
87 case 2:
88 case 3:
89 MeshTools::Modification::translate(*mesh, vector_value(0), vector_value(1), vector_value(2));
90 // libMesh translate() fails to properly mark the spatial
91 // dimension as unprepared in cases where we've displaced a 1D
92 // mesh in y or z or a 2D mesh in z. Until that's fixed we work
93 // around the bug.
94 mesh->unset_has_cached_elem_data();
95 break;
96 case 4:
97 MeshTools::Modification::rotate(*mesh, vector_value(0), vector_value(1), vector_value(2));
98 // libMesh rotate() tries to set the spatial dimension properly,
99 // and probably does for all realistic use cases, but there are
100 // at least hypothetical cases where it could be wrong.
101 //
102 // Until that's fixed we work around it.
103 mesh->unset_has_cached_elem_data();
104 break;
105 case 5:
106 MeshTools::Modification::scale(*mesh, vector_value(0), vector_value(1), vector_value(2));
107 // Is anybody using scale() to just squash a manifold's spatial
108 // dimension down to its mesh dimension? Let's be safe until
109 // libMesh is handling that case.
110 mesh->unset_has_cached_elem_data();
111 break;
112 case 6:
114 break;
115 case 7:
116 TransformGenerator::rotateExtrinsic(*mesh, vector_value(0), vector_value(1), vector_value(2));
117 break;
118 }
119
120 mesh->unset_is_prepared();
121 return dynamic_pointer_cast<MeshBase>(mesh);
122}
123
124void
126 const Real alpha,
127 const Real beta,
128 const Real gamma)
129{
130#if LIBMESH_DIM == 3
131 const auto R = RealTensorValue::extrinsic_rotation_matrix(
132 alpha, beta, gamma); // this line is the only difference from rotate...
133
134 // Let's not try to guess what this did to our spatial dimension (it
135 // could have reduced it, depending on the input mesh!), let's just
136 // mark that it needs to be recomputed.
137 mesh.unset_has_cached_elem_data();
138
139 for (auto & node : mesh.node_ptr_range())
140 {
141 Point & pt = *node;
142 pt = R * pt;
143 }
144#else
145 libmesh_ignore(mesh, alpha, beta, gamma);
146 libmesh_error_msg(
147 "MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
148#endif
149}
150
151void
153 const GenericRealTensorValue<false> & rotation_matrix)
154{
155#if LIBMESH_DIM == 3
156 // Let's not try to guess what this did to our spatial dimension,
157 // let's just mark that it needs to be recomputed.
158 mesh.unset_has_cached_elem_data();
159
160 for (auto & node : mesh.node_ptr_range())
161 {
162 Point & pt = *node;
163 pt = rotation_matrix * pt;
164 }
165
166#else
167 libmesh_ignore(mesh, phi, theta, psi);
168 libmesh_error_msg(
169 "MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
170#endif
171}
Moose::GenericType< RealTensorValue, is_ad > GenericRealTensorValue
Definition MooseTypes.h:704
registerMooseObject("MooseApp", TransformGenerator)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
void rotateExtrinsic(MeshBase &mesh, const Real alpha, const Real beta, const Real gamma)
Rotate the mesh using extrinsic rotation with given angles.
std::unique_ptr< MeshBase > & _input
the input mesh
void rotateWithMatrix(MeshBase &mesh, const GenericRealTensorValue< false > &rotation_matrix)
Rotate a mesh using a given rotation matrix.
const MooseEnum _transform
the transform to apply to the mesh
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
TransformGenerator(const InputParameters &parameters)
static InputParameters validParams()
MeshBase & mesh
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)