LCOV - code coverage report
Current view: top level - src/bcs - DisplacementAboutAxis.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 145 146 99.3 %
Date: 2025-07-25 05:00:39 Functions: 8 8 100.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 "DisplacementAboutAxis.h"
      11             : #include "Function.h"
      12             : 
      13             : registerMooseObject("SolidMechanicsApp", DisplacementAboutAxis);
      14             : 
      15             : InputParameters
      16         636 : DisplacementAboutAxis::validParams()
      17             : {
      18         636 :   InputParameters params = DirichletBCBase::validParams();
      19         636 :   params.addClassDescription("Implements a boundary condition that enforces rotational"
      20             :                              "displacement around an axis on a boundary");
      21         636 :   addDisplacementAboutAxisParams(params);
      22        1272 :   params.addRequiredParam<int>("component", "The component for the rotational displacement");
      23         636 :   params.set<bool>("use_displaced_mesh") = false;
      24         636 :   params.set<bool>("preset") = true;
      25         636 :   return params;
      26           0 : }
      27             : 
      28             : void
      29         636 : addDisplacementAboutAxisParams(InputParameters & params)
      30             : {
      31        1272 :   MooseEnum units("degrees radians");
      32        1272 :   params.addRequiredParam<FunctionName>(
      33             :       "function", "The function providing the total angle of rotation or the angular velocity.");
      34        1272 :   params.addRequiredParam<MooseEnum>("angle_units",
      35             :                                      units,
      36         636 :                                      "The units of the angle of rotation. Choices are:" +
      37         636 :                                          units.getRawNames());
      38        1272 :   params.addRequiredParam<RealVectorValue>("axis_origin", "Origin of the axis of rotation");
      39        1272 :   params.addRequiredParam<RealVectorValue>("axis_direction", "Direction of the axis of rotation");
      40        1272 :   params.addParam<bool>(
      41        1272 :       "angular_velocity", false, "If true interprets the function value as an angular velocity");
      42        1272 :   params.addRequiredCoupledVar("displacements",
      43             :                                "The string of displacements suitable for the problem statement");
      44         636 : }
      45             : 
      46         320 : DisplacementAboutAxis::DisplacementAboutAxis(const InputParameters & parameters)
      47             :   : DirichletBCBase(parameters),
      48         320 :     _component(getParam<int>("component")),
      49         320 :     _func(getFunction("function")),
      50         640 :     _angle_units(getParam<MooseEnum>("angle_units")),
      51         320 :     _axis_origin(getParam<RealVectorValue>("axis_origin")),
      52         320 :     _axis_direction(getParam<RealVectorValue>("axis_direction")),
      53         320 :     _ndisp(coupledComponents("displacements")),
      54         320 :     _disp_old(_ndisp),
      55         960 :     _angular_velocity(getParam<bool>("angular_velocity"))
      56             : {
      57         320 :   if (_component < 0 || _component > 2)
      58           2 :     mooseError("Invalid component given for ", name(), ": ", _component, ".");
      59             : 
      60         318 :   if (_axis_direction.norm() == 0.)
      61           2 :     mooseError("Please specify a non-zero direction vector for the axis_direction in ", name());
      62         316 : }
      63             : 
      64             : void
      65         312 : DisplacementAboutAxis::initialSetup()
      66             : {
      67         312 :   calculateUnitDirectionVector();
      68         312 :   calculateTransformationMatrices();
      69             : 
      70         312 :   if (_angular_velocity)
      71         888 :     for (unsigned int i = 0; i < _ndisp; ++i)
      72         666 :       _disp_old[i] = &coupledDofValuesOld("displacements", i);
      73             :   else
      74         360 :     for (unsigned int i = 0; i < _ndisp; ++i)
      75         270 :       _disp_old[i] = nullptr;
      76         312 : }
      77             : 
      78             : Real
      79      266496 : DisplacementAboutAxis::computeQpValue()
      80             : {
      81      266496 :   Point p(*_current_node);
      82             : 
      83      266496 :   Real angle(_func.value(_t, *_current_node));
      84      266496 :   if (_angle_units == "degrees")
      85      266496 :     angle = angle * libMesh::pi / 180.0;
      86             : 
      87      266496 :   if (_angular_velocity)
      88      109760 :     angle *= _dt;
      89             : 
      90      266496 :   ColumnMajorMatrix p_old(4, 1);
      91      266496 :   p_old(0, 0) = p(0);
      92      266496 :   p_old(1, 0) = p(1);
      93      266496 :   p_old(2, 0) = p(2);
      94      266496 :   p_old(3, 0) = 1;
      95             : 
      96      266496 :   if (_angular_velocity)
      97      439040 :     for (unsigned int i = 0; i < _ndisp; i++)
      98      329280 :       p_old(i, 0) += (*_disp_old[i])[_qp];
      99             : 
     100      266496 :   ColumnMajorMatrix p_new = rotateAroundAxis(p_old, angle);
     101             : 
     102      532992 :   return p_new(_component, 0) - p(_component);
     103             : }
     104             : 
     105             : ColumnMajorMatrix
     106      266496 : DisplacementAboutAxis::rotateAroundAxis(const ColumnMajorMatrix & p0, const Real angle)
     107             : {
     108      266496 :   ColumnMajorMatrix rotate_about_z(4, 4);
     109      266496 :   rotate_about_z(0, 0) = cos(angle);
     110      266496 :   rotate_about_z(0, 1) = -sin(angle);
     111      266496 :   rotate_about_z(0, 2) = 0;
     112      266496 :   rotate_about_z(0, 3) = 0;
     113      266496 :   rotate_about_z(1, 0) = sin(angle);
     114      266496 :   rotate_about_z(1, 1) = cos(angle);
     115      266496 :   rotate_about_z(1, 2) = 0;
     116      266496 :   rotate_about_z(1, 3) = 0;
     117      266496 :   rotate_about_z(2, 0) = 0;
     118      266496 :   rotate_about_z(2, 1) = 0;
     119      266496 :   rotate_about_z(2, 2) = 1;
     120      266496 :   rotate_about_z(2, 3) = 0;
     121      266496 :   rotate_about_z(3, 0) = 0;
     122      266496 :   rotate_about_z(3, 1) = 0;
     123      266496 :   rotate_about_z(3, 2) = 0;
     124      266496 :   rotate_about_z(3, 3) = 1;
     125             : 
     126             :   ColumnMajorMatrix transform =
     127      266496 :       _transformation_matrix_inv * rotate_about_z * _transformation_matrix;
     128      532992 :   return transform * p0;
     129             : }
     130             : 
     131             : void
     132         312 : DisplacementAboutAxis::calculateUnitDirectionVector()
     133             : {
     134         312 :   Real magnitude = _axis_direction.norm();
     135             :   _axis_direction /= magnitude;
     136         312 : }
     137             : 
     138             : void
     139         312 : DisplacementAboutAxis::calculateTransformationMatrices()
     140             : {
     141             :   // These parts of the transformation matrix only depend on the axis of rotation:
     142             : 
     143             :   Real length = _axis_direction.norm_sq();
     144         312 :   Real v = _axis_direction(1) * _axis_direction(1) + _axis_direction(2) * _axis_direction(2);
     145             : 
     146         312 :   ColumnMajorMatrix transl(4, 4);
     147         312 :   transl(0, 0) = 1;
     148         312 :   transl(0, 1) = 0;
     149         312 :   transl(0, 2) = 0;
     150         312 :   transl(0, 3) = -_axis_origin(0);
     151         312 :   transl(1, 0) = 0;
     152         312 :   transl(1, 1) = 1;
     153         312 :   transl(1, 2) = 0;
     154         312 :   transl(1, 3) = -_axis_origin(1);
     155         312 :   transl(2, 0) = 0;
     156         312 :   transl(2, 1) = 0;
     157         312 :   transl(2, 2) = 1;
     158         312 :   transl(2, 3) = -_axis_origin(2);
     159         312 :   transl(3, 0) = 0;
     160         312 :   transl(3, 1) = 0;
     161         312 :   transl(3, 2) = 0;
     162         312 :   transl(3, 3) = 1;
     163             : 
     164         312 :   ColumnMajorMatrix rotate_about_x(4, 4);
     165         312 :   rotate_about_x(0, 0) = 1;
     166         312 :   rotate_about_x(0, 1) = 0;
     167         312 :   rotate_about_x(0, 2) = 0;
     168         312 :   rotate_about_x(0, 3) = 0;
     169         312 :   rotate_about_x(1, 0) = 0;
     170         312 :   rotate_about_x(1, 1) = _axis_direction(2) / v;
     171         312 :   rotate_about_x(1, 2) = -_axis_direction(1) / v;
     172         312 :   rotate_about_x(1, 3) = 0;
     173         312 :   rotate_about_x(2, 0) = 0;
     174         312 :   rotate_about_x(2, 1) = _axis_direction(1) / v;
     175         312 :   rotate_about_x(2, 2) = _axis_direction(2) / v;
     176         312 :   rotate_about_x(2, 3) = 0;
     177         312 :   rotate_about_x(3, 0) = 0;
     178         312 :   rotate_about_x(3, 1) = 0;
     179         312 :   rotate_about_x(3, 2) = 0;
     180         312 :   rotate_about_x(3, 3) = 1;
     181             : 
     182         312 :   ColumnMajorMatrix rotate_about_y(4, 4);
     183         312 :   rotate_about_y(0, 0) = v / length;
     184         312 :   rotate_about_y(0, 1) = 0;
     185         312 :   rotate_about_y(0, 2) = -_axis_direction(0) / length;
     186         312 :   rotate_about_y(0, 3) = 0;
     187         312 :   rotate_about_y(1, 0) = 0;
     188         312 :   rotate_about_y(1, 1) = 1;
     189         312 :   rotate_about_y(1, 2) = 0;
     190         312 :   rotate_about_y(1, 3) = 0;
     191         312 :   rotate_about_y(2, 0) = _axis_direction(0) / length;
     192         312 :   rotate_about_y(2, 1) = 0;
     193         312 :   rotate_about_y(2, 2) = v / length;
     194         312 :   rotate_about_y(2, 3) = 0;
     195         312 :   rotate_about_y(3, 0) = 0;
     196         312 :   rotate_about_y(3, 1) = 0;
     197         312 :   rotate_about_y(3, 2) = 0;
     198         312 :   rotate_about_y(3, 3) = 1;
     199             : 
     200         312 :   ColumnMajorMatrix transl_inv(4, 4);
     201         312 :   transl.inverse(transl_inv);
     202         312 :   ColumnMajorMatrix rotx_inv(4, 4);
     203         312 :   rotate_about_x.inverse(rotx_inv);
     204         312 :   ColumnMajorMatrix roty_inv(4, 4);
     205         312 :   rotate_about_y.inverse(roty_inv);
     206             : 
     207         312 :   _transformation_matrix = rotate_about_y * rotate_about_x * transl;
     208         624 :   _transformation_matrix_inv = transl_inv * rotx_inv * roty_inv;
     209         312 : }

Generated by: LCOV version 1.14