LCOV - code coverage report
Current view: top level - src/functions - Axisymmetric2D3DSolutionFunction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 21 115 18.3 %
Date: 2025-07-17 01:28:37 Functions: 1 4 25.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14