Line data Source code
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 "MooseError.h"
11 : #include "Axisymmetric2D3DSolutionFunction.h"
12 : #include "SolutionUserObjectBase.h"
13 :
14 : registerMooseObject("MooseApp", Axisymmetric2D3DSolutionFunction);
15 :
16 : InputParameters
17 14265 : Axisymmetric2D3DSolutionFunction::validParams()
18 : {
19 : // Get the Function input parameters
20 14265 : InputParameters params = Function::validParams();
21 :
22 : // Add parameters specific to this object
23 14265 : params.addRequiredParam<UserObjectName>("solution",
24 : "The SolutionUserObject to extract data from.");
25 14265 : params.addParam<std::vector<std::string>>(
26 : "from_variables",
27 : "The names of the variables in the file that are to be extracted, in x, y "
28 : "order if they are vector components");
29 :
30 42795 : params.addParam<Real>(
31 : "scale_factor",
32 28530 : 1.0,
33 : "Scale factor (a) to be applied to the solution (x): ax+b, where b is the 'add_factor'");
34 42795 : params.addParam<Real>(
35 : "add_factor",
36 28530 : 0.0,
37 : "Add this value (b) to the solution (x): ax+b, where a is the 'scale_factor'");
38 42795 : params.addParam<Real>("axial_dimension_ratio",
39 28530 : 1.0,
40 : "Ratio of the axial dimension in the 3d model to that in the 2d model. "
41 : "Optionally permits the 3d model to be larger than the 2d model in that "
42 : "dimension, and scales vector solutions in that direction by this factor.");
43 :
44 42795 : params.addParam<RealVectorValue>("2d_axis_point1",
45 28530 : RealVectorValue(0, 0, 0),
46 : "Start point for axis of symmetry for the 2d model");
47 42795 : params.addParam<RealVectorValue>("2d_axis_point2",
48 28530 : RealVectorValue(0, 1, 0),
49 : "End point for axis of symmetry for the 2d model");
50 42795 : params.addParam<RealVectorValue>("3d_axis_point1",
51 28530 : RealVectorValue(0, 0, 0),
52 : "Start point for axis of symmetry for the 3d model");
53 42795 : params.addParam<RealVectorValue>("3d_axis_point2",
54 28530 : RealVectorValue(0, 1, 0),
55 : "End point for axis of symmetry for the 3d model");
56 :
57 14265 : params.addParam<unsigned int>("component",
58 : "Component of the variable to be computed if it is a vector");
59 :
60 14265 : params.addClassDescription("Function for reading a 2D axisymmetric solution from file and "
61 : "mapping it to a 3D Cartesian model");
62 :
63 14265 : return params;
64 0 : }
65 :
66 0 : Axisymmetric2D3DSolutionFunction::Axisymmetric2D3DSolutionFunction(
67 0 : const InputParameters & parameters)
68 : : Function(parameters),
69 0 : _solution_object_ptr(NULL),
70 0 : _scale_factor(getParam<Real>("scale_factor")),
71 0 : _add_factor(getParam<Real>("add_factor")),
72 0 : _axial_dim_ratio(getParam<Real>("axial_dimension_ratio")),
73 0 : _2d_axis_point1(getParam<RealVectorValue>("2d_axis_point1")),
74 0 : _2d_axis_point2(getParam<RealVectorValue>("2d_axis_point2")),
75 0 : _3d_axis_point1(getParam<RealVectorValue>("3d_axis_point1")),
76 0 : _3d_axis_point2(getParam<RealVectorValue>("3d_axis_point2")),
77 0 : _has_component(isParamValid("component")),
78 0 : _component(_has_component ? getParam<unsigned int>("component") : 99999),
79 0 : _var_names(getParam<std::vector<std::string>>("from_variables"))
80 : {
81 0 : if (_has_component && _var_names.size() != 2)
82 0 : mooseError("Must supply names of 2 variables in 'from_variables' if 'component' is specified");
83 0 : else if (!_has_component && _var_names.size() == 2)
84 0 : mooseError("Must supply 'component' if 2 variables specified in 'from_variables'");
85 0 : else if (_var_names.size() > 2)
86 0 : mooseError("If 'from_variables' is specified, it must have either 1 (scalar) or 2 (vector "
87 : "components) variables");
88 :
89 0 : Point zero;
90 0 : Point unit_vec_y;
91 0 : unit_vec_y(1) = 1;
92 0 : if (_2d_axis_point1 == zero && _2d_axis_point2 == unit_vec_y && _3d_axis_point1 == zero &&
93 0 : _3d_axis_point2 == unit_vec_y)
94 0 : _default_axes = true;
95 : else
96 0 : _default_axes = false;
97 :
98 0 : if (_3d_axis_point1.relative_fuzzy_equals(_3d_axis_point2))
99 0 : mooseError("3d_axis_point1 and 3d_axis_point2 must be different points");
100 0 : if (_2d_axis_point1.relative_fuzzy_equals(_2d_axis_point2))
101 0 : mooseError("2d_axis_point1 and 2d_axis_point2 must be different points");
102 0 : }
103 :
104 : void
105 0 : Axisymmetric2D3DSolutionFunction::initialSetup()
106 : {
107 : // Get a pointer to the SolutionUserObject. A pointer is used because the UserObject is not
108 : // available during the
109 : // construction of the function
110 0 : _solution_object_ptr = &getUserObject<SolutionUserObjectBase>("solution");
111 :
112 : // If 'from_variable' is not specified, get the value from the SolutionUserObject
113 0 : if (_var_names.size() == 0)
114 : {
115 : // Get all the variables from the SolutionUserObject
116 0 : const std::vector<std::string> & vars = _solution_object_ptr->variableNames();
117 :
118 : // If there are more than one, throw an error
119 0 : if (vars.size() > 1)
120 0 : mooseError("If the SolutionUserObject contains multiple variables, the variable name must be "
121 : "specified in the input file with 'from_variables'");
122 :
123 : // Define the variable
124 0 : _var_names.push_back(vars[0]);
125 : }
126 0 : if (_2d_axis_point1(2) != 0)
127 0 : mooseError("3rd component of 2d_axis_point1 must be zero");
128 0 : if (_2d_axis_point2(2) != 0)
129 0 : mooseError("3rd component of 2d_axis_point2 must be zero");
130 :
131 0 : _solution_object_var_indices.resize(_var_names.size());
132 0 : for (unsigned int i = 0; i < _var_names.size(); ++i)
133 0 : _solution_object_var_indices[i] = _solution_object_ptr->getLocalVarIndex(_var_names[i]);
134 0 : }
135 :
136 : Real
137 0 : Axisymmetric2D3DSolutionFunction::value(Real t, const Point & p) const
138 : {
139 0 : Point xypoint;
140 0 : Point r_dir_2d;
141 0 : Point z_dir_2d;
142 0 : Point r_dir_3d;
143 0 : Point z_dir_3d;
144 0 : bool r_gt_zero = false;
145 :
146 0 : if (_default_axes)
147 : {
148 0 : r_dir_2d(0) = 1;
149 0 : z_dir_2d(1) = 1;
150 0 : r_dir_3d = p;
151 0 : r_dir_3d(1) = 0;
152 0 : Real r = r_dir_3d.norm();
153 0 : if (MooseUtils::absoluteFuzzyGreaterThan(r, 0.0))
154 : {
155 0 : r_gt_zero = true;
156 0 : r_dir_3d /= r;
157 : }
158 0 : z_dir_3d(1) = 1;
159 0 : xypoint(0) = std::sqrt(p(0) * p(0) + p(2) * p(2));
160 0 : xypoint(1) = p(1) / _axial_dim_ratio;
161 : }
162 : else
163 : {
164 : // Find the r, z coordinates of the point in the 3D model relative to the 3D axis
165 0 : z_dir_3d = _3d_axis_point2 - _3d_axis_point1;
166 0 : z_dir_3d /= z_dir_3d.norm();
167 0 : Point v3dp1p(p - _3d_axis_point1);
168 0 : Real z = z_dir_3d * v3dp1p;
169 0 : Point axis_proj = _3d_axis_point1 + z * z_dir_3d; // projection of point onto axis
170 0 : Point axis_proj_to_p = p - axis_proj;
171 0 : Real r = axis_proj_to_p.norm();
172 0 : if (MooseUtils::absoluteFuzzyGreaterThan(r, 0.0))
173 : {
174 0 : r_gt_zero = true;
175 0 : r_dir_3d = axis_proj_to_p / r;
176 : }
177 :
178 : // Convert point in r, z coordinates into x, y coordinates
179 0 : z_dir_2d = _2d_axis_point2 - _2d_axis_point1;
180 0 : z_dir_2d /= z_dir_2d.norm();
181 0 : Point out_of_plane_vec(0, 0, 1);
182 0 : r_dir_2d = z_dir_2d.cross(out_of_plane_vec);
183 0 : r_dir_2d /= r_dir_2d.norm(); // size should be 1, maybe this isn't necessary
184 0 : xypoint = _2d_axis_point1 + z / _axial_dim_ratio * z_dir_2d + r * r_dir_2d;
185 : }
186 :
187 : Real val;
188 0 : if (_has_component)
189 : {
190 0 : Real val_x = _solution_object_ptr->pointValue(t, xypoint, _solution_object_var_indices[0]);
191 0 : Real val_y = _solution_object_ptr->pointValue(t, xypoint, _solution_object_var_indices[1]);
192 :
193 : // val_vec_rz contains the value vector converted from x,y to r,z coordinates
194 0 : Point val_vec_rz;
195 0 : val_vec_rz(0) = r_dir_2d(0) * val_x + r_dir_2d(1) * val_y;
196 0 : val_vec_rz(1) = z_dir_2d(0) * val_x + z_dir_2d(1) * val_y;
197 0 : if (!r_gt_zero && !MooseUtils::absoluteFuzzyEqual(val_vec_rz(0), 0.0))
198 0 : mooseError("In Axisymmetric2D3DSolutionFunction r=0 and r component of value vector != 0");
199 0 : Point val_vec_3d = val_vec_rz(0) * r_dir_3d + val_vec_rz(1) * z_dir_3d;
200 :
201 0 : val = val_vec_3d(_component);
202 : }
203 : else
204 0 : val = _solution_object_ptr->pointValue(t, xypoint, _solution_object_var_indices[0]);
205 :
206 0 : return _scale_factor * val + _add_factor;
207 : }
|