LCOV - code coverage report
Current view: top level - src/materials - ComputeIsolatorDeformation.C (source / functions) Hit Total Coverage
Test: idaholab/mastodon: 55510a Lines: 127 129 98.4 %
Date: 2025-08-26 23:09:31 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*************************************************/
       2             : /*           DO NOT MODIFY THIS HEADER           */
       3             : /*                                               */
       4             : /*                     MASTODON                  */
       5             : /*                                               */
       6             : /*    (c) 2015 Battelle Energy Alliance, LLC     */
       7             : /*            ALL RIGHTS RESERVED                */
       8             : /*                                               */
       9             : /*   Prepared by Battelle Energy Alliance, LLC   */
      10             : /*     With the U. S. Department of Energy       */
      11             : /*                                               */
      12             : /*     See COPYRIGHT for full restrictions       */
      13             : /*************************************************/
      14             : 
      15             : // MASTODON includes
      16             : #include "ComputeIsolatorDeformation.h"
      17             : 
      18             : // MOOSE includes
      19             : #include "MooseMesh.h"
      20             : #include "Assembly.h"
      21             : #include "NonlinearSystem.h"
      22             : #include "MooseVariable.h"
      23             : #include "ColumnMajorMatrix.h"
      24             : 
      25             : // libmesh includes
      26             : #include "libmesh/quadrature.h"
      27             : #include "libmesh/utility.h"
      28             : 
      29             : registerMooseObject("MastodonApp", ComputeIsolatorDeformation);
      30             : 
      31             : InputParameters
      32         165 : ComputeIsolatorDeformation::validParams()
      33             : {
      34         165 :   InputParameters params = Material::validParams();
      35         165 :   params.addClassDescription(
      36             :       "Compute the deformations and rotations in a two-noded isolator element.");
      37         330 :   params.addRequiredCoupledVar(
      38             :       "rotations",
      39             :       "The rotation variables appropriate for the simulation geometry and coordinate system.");
      40         330 :   params.addRequiredCoupledVar(
      41             :       "displacements",
      42             :       "The displacement variables appropriate for the simulation geometry and coordinate system.");
      43         330 :   params.addRequiredCoupledVar("velocities", "Translational velocity variables.");
      44         330 :   params.addRequiredParam<RealGradient>("y_orientation",
      45             :                                         "Orientation of the local Y direction along "
      46             :                                         "which, Ky is provided. This should be "
      47             :                                         "perpendicular to the axis of the isolator.");
      48         330 :   params.addParam<MaterialPropertyName>("sd_ratio", 0.5, "Shear distance ratio.");
      49         330 :   params.set<MooseEnum>("constant_on") = "ELEMENT"; // sets _qp to 0. Material properties are
      50             :                                                     // assumed to be constant throughout the length
      51             :                                                     // of the element.
      52         165 :   return params;
      53           0 : }
      54             : 
      55         124 : ComputeIsolatorDeformation::ComputeIsolatorDeformation(const InputParameters & parameters)
      56             :   : Material(parameters),
      57         124 :     _nrot(coupledComponents("rotations")),
      58         124 :     _ndisp(coupledComponents("displacements")),
      59         124 :     _nvel(coupledComponents("velocities")),
      60         124 :     _rot_num(3),
      61         124 :     _disp_num(3),
      62         124 :     _vel_num(3),
      63         248 :     _sD(getMaterialProperty<Real>("sd_ratio")),
      64         124 :     _local_disp(declareProperty<ColumnMajorMatrix>("local_deformations")),
      65         124 :     _basic_disp(declareProperty<ColumnMajorMatrix>("deformations")),
      66         124 :     _basic_disp_old(declareProperty<ColumnMajorMatrix>("old_deformations")),
      67         124 :     _basic_vel(declareProperty<ColumnMajorMatrix>("deformation_rates")),
      68         124 :     _basic_vel_old(declareProperty<ColumnMajorMatrix>("old_deformation_rates")),
      69         124 :     _original_gl(declareProperty<ColumnMajorMatrix>("original_global_to_local_transformation")),
      70         124 :     _total_gl(declareProperty<ColumnMajorMatrix>("total_global_to_local_transformation")),
      71         124 :     _total_lb(declareProperty<ColumnMajorMatrix>("total_local_to_basic_transformation")),
      72         248 :     _length(declareProperty<Real>("initial_isolator_length"))
      73             : {
      74             : 
      75             :   // Checking for consistency between length of the provided displacements and rotations vector
      76         124 :   if (_ndisp != _nrot)
      77           1 :     mooseError("Error in ComputeIsolatorDeformation block, ",
      78             :                name(),
      79             :                ". The number of variables supplied in 'displacements' "
      80             :                "and 'rotations' input parameters must be equal.");
      81             : 
      82             :   // Fetch coupled variables and gradients (as stateful properties if necessary)
      83         492 :   for (unsigned int i = 0; i < _ndisp; ++i)
      84             :   {
      85         738 :     MooseVariable * disp_variable = getVar("displacements", i);
      86         369 :     _disp_num[i] = disp_variable->number(); // Displacement variable numbers in MOOSE
      87             : 
      88         738 :     MooseVariable * vel_variable = getVar("velocities", i);
      89         369 :     _vel_num[i] = vel_variable->number();
      90             : 
      91         738 :     MooseVariable * rot_variable = getVar("rotations", i);
      92         369 :     _rot_num[i] = rot_variable->number(); // Rotation variable numbers in MOOSE
      93             :   }
      94         123 : }
      95             : 
      96             : void
      97       44425 : ComputeIsolatorDeformation::computeQpProperties()
      98             : {
      99             :   // Compute initial orientation and length of the isolator in global coordinate system
     100             :   // Fetch the two nodes of the link element
     101             :   std::vector<const Node *> node;
     102      133275 :   for (unsigned int i = 0; i < 2; ++i)
     103       88850 :     node.push_back(_current_elem->node_ptr(i));
     104             :   RealGradient x_orientation;
     105      177700 :   for (unsigned int i = 0; i < _ndisp; ++i)
     106      133275 :     x_orientation(i) = (*node[1])(i) - (*node[0])(i);
     107       44425 :   _length[_qp] = x_orientation.norm();
     108       44425 :   if (_length[_qp] == 0.0)
     109           0 :     mooseError("Error in ComputeIsolatorDeformation block, ",
     110             :                name(),
     111             :                ". Isolator element cannot be of zero length.");
     112             :   x_orientation /= _length[_qp]; // Normalizing with length to get orientation
     113             : 
     114             :   // Get y orientation of the isolator in global coordinate system
     115       88850 :   RealGradient y_orientation = getParam<RealGradient>("y_orientation");
     116             :   Real dot = x_orientation * y_orientation;
     117             : 
     118             :   // Check if x and y orientations are perpendicular
     119       44425 :   if (abs(dot) > 1e-4)
     120           1 :     mooseError("Error in ComputeIsolatorDeformation block, ",
     121             :                name(),
     122             :                ". 'y_orientation' should be perpendicular to ",
     123             :                "the axis of the isolator.");
     124             : 
     125             :   // Calculate z orientation in the global coordinate system as a cross product of the x and y
     126             :   // orientations
     127       44424 :   RealGradient z_orientation = x_orientation.cross(y_orientation);
     128             : 
     129             :   // Create rotation matrix from global to local coordinate system
     130       44424 :   _original_gl[_qp].reshape(12, 12);
     131       44424 :   _original_gl[_qp].zero();
     132       44424 :   _original_gl[_qp](0, 0) = _original_gl[_qp](3, 3) = _original_gl[_qp](6, 6) =
     133       44424 :       _original_gl[_qp](9, 9) = x_orientation(0);
     134       44424 :   _original_gl[_qp](0, 1) = _original_gl[_qp](3, 4) = _original_gl[_qp](6, 7) =
     135       44424 :       _original_gl[_qp](9, 10) = x_orientation(1);
     136       44424 :   _original_gl[_qp](0, 2) = _original_gl[_qp](3, 5) = _original_gl[_qp](6, 8) =
     137       44424 :       _original_gl[_qp](9, 11) = x_orientation(2);
     138       44424 :   _original_gl[_qp](1, 0) = _original_gl[_qp](4, 3) = _original_gl[_qp](7, 6) =
     139       44424 :       _original_gl[_qp](10, 9) = y_orientation(0);
     140       44424 :   _original_gl[_qp](1, 1) = _original_gl[_qp](4, 4) = _original_gl[_qp](7, 7) =
     141       44424 :       _original_gl[_qp](10, 10) = y_orientation(1);
     142       44424 :   _original_gl[_qp](1, 2) = _original_gl[_qp](4, 5) = _original_gl[_qp](7, 8) =
     143       44424 :       _original_gl[_qp](10, 11) = y_orientation(2);
     144       44424 :   _original_gl[_qp](2, 0) = _original_gl[_qp](5, 3) = _original_gl[_qp](8, 6) =
     145       44424 :       _original_gl[_qp](11, 9) = z_orientation(0);
     146       44424 :   _original_gl[_qp](2, 1) = _original_gl[_qp](5, 4) = _original_gl[_qp](8, 7) =
     147       44424 :       _original_gl[_qp](11, 10) = z_orientation(1);
     148       44424 :   _original_gl[_qp](2, 2) = _original_gl[_qp](5, 5) = _original_gl[_qp](8, 8) =
     149       44424 :       _original_gl[_qp](11, 11) = z_orientation(2);
     150             : 
     151             :   // Create rotation matrix from local to basic system (linear)
     152       44424 :   _total_lb[_qp].reshape(6, 12);
     153       44424 :   _total_lb[_qp].zero();
     154       44424 :   _total_lb[_qp](0, 0) = _total_lb[_qp](1, 1) = _total_lb[_qp](2, 2) = _total_lb[_qp](3, 3) =
     155       44424 :       _total_lb[_qp](4, 4) = _total_lb[_qp](5, 5) = -1.0;
     156       44424 :   _total_lb[_qp](0, 6) = _total_lb[_qp](1, 7) = _total_lb[_qp](2, 8) = _total_lb[_qp](3, 9) =
     157       44424 :       _total_lb[_qp](4, 10) = _total_lb[_qp](5, 11) = 1.0;
     158       44424 :   _total_lb[_qp](1, 5) = -_sD[0] * _length[_qp];
     159       44424 :   _total_lb[_qp](1, 11) = -(1.0 - _sD[0]) * _length[_qp];
     160       44424 :   _total_lb[_qp](2, 4) = -_total_lb[_qp](1, 5);
     161       44424 :   _total_lb[_qp](2, 10) = -_total_lb[_qp](1, 11);
     162             : 
     163       44424 :   computeTotalRotation();
     164       44424 :   computeDeformation();
     165       44424 : }
     166             : 
     167             : void
     168       44424 : ComputeIsolatorDeformation::computeTotalRotation()
     169             : {
     170             :   std::size_t _qp = 0;
     171             :   // Currently, this formulation is limited to small deformations in the isolator,
     172             :   // namely, it is assumed that there are no rigid body rotations in the isolator,
     173             :   // and that the total rotation matrix from global to local coordinates
     174             :   // (calculated below) remains the same as the one at t = 0 throughout the
     175             :   // duration of the simulation.
     176       44424 :   _total_gl[_qp] = _original_gl[_qp];
     177       44424 : }
     178             : 
     179             : void
     180       44424 : ComputeIsolatorDeformation::computeDeformation()
     181             : {
     182             :   // fetch the two end nodes for _current_elem
     183             :   std::vector<const Node *> node;
     184      133272 :   for (unsigned int i = 0; i < 2; ++i)
     185       88848 :     node.push_back(_current_elem->node_ptr(i));
     186             : 
     187             :   // Fetch the solution for the two end nodes at time t
     188       44424 :   NonlinearSystemBase & nonlinear_sys = _fe_problem.getNonlinearSystemBase(/*nl_sys_num=*/0);
     189       44424 :   const NumericVector<Number> & sol = *nonlinear_sys.currentSolution();
     190       44424 :   const NumericVector<Number> & sol_old = nonlinear_sys.solutionOld();
     191             : 
     192       44424 :   AuxiliarySystem & aux = _fe_problem.getAuxiliarySystem();
     193       44424 :   const NumericVector<Number> & aux_sol = *aux.currentSolution();
     194       44424 :   const NumericVector<Number> & aux_sol_old = aux.solutionOld();
     195             : 
     196             :   // Calculating global displacements (including rotations) and velocities (rotational velocity
     197             :   // terms are zero) 12 x 1 matrix with first six rows corresponding to node 0 dofs and next six to
     198             :   // node 1 dofs
     199       44424 :   ColumnMajorMatrix global_disp(12, 1);
     200       44424 :   ColumnMajorMatrix global_vel(12, 1);
     201       44424 :   ColumnMajorMatrix global_disp_old(12, 1);
     202       44424 :   ColumnMajorMatrix global_vel_old(12, 1);
     203      177696 :   for (unsigned int i = 0; i < _ndisp; ++i)
     204             :   {
     205      133272 :     global_disp(i) =
     206      133272 :         sol(node[0]->dof_number(nonlinear_sys.number(), _disp_num[i], 0)); // node 0 displacements
     207      133272 :     global_disp(i + 3) =
     208      133272 :         sol(node[0]->dof_number(nonlinear_sys.number(), _rot_num[i], 0)); // node 0 rotations
     209      133272 :     global_disp(i + 6) =
     210      133272 :         sol(node[1]->dof_number(nonlinear_sys.number(), _disp_num[i], 0)); // node 1 displacements
     211      133272 :     global_disp(i + 9) =
     212      133272 :         sol(node[1]->dof_number(nonlinear_sys.number(), _rot_num[i], 0)); // node 1 rotations
     213      133272 :     global_disp_old(i) = sol_old(
     214             :         node[0]->dof_number(nonlinear_sys.number(), _disp_num[i], 0)); // node 0 displacements
     215      133272 :     global_disp_old(i + 3) =
     216      133272 :         sol_old(node[0]->dof_number(nonlinear_sys.number(), _rot_num[i], 0)); // node 0 rotations
     217      133272 :     global_disp_old(i + 6) = sol_old(
     218             :         node[1]->dof_number(nonlinear_sys.number(), _disp_num[i], 0)); // node 1 displacements
     219      133272 :     global_disp_old(i + 9) =
     220      133272 :         sol_old(node[1]->dof_number(nonlinear_sys.number(), _rot_num[i], 0)); // node 1 rotations
     221      133272 :     global_vel(i) = aux_sol(node[0]->dof_number(
     222             :         aux.number(), _vel_num[i], 0)); // node 0 velocities; rotational velocity terms remain zero
     223      133272 :     global_vel(i + 6) = aux_sol_old(node[1]->dof_number(
     224             :         aux.number(), _vel_num[i], 0)); // node 1 velocities; rotational velocity terms remain zero
     225      133272 :     global_vel_old(i) = aux_sol_old(node[0]->dof_number(
     226             :         aux.number(), _vel_num[i], 0)); // node 0 velocities; rotational velocity terms remain zero
     227      133272 :     global_vel_old(i + 6) = aux_sol_old(node[1]->dof_number(
     228             :         aux.number(), _vel_num[i], 0)); // node 1 velocities; rotational velocity terms remain zero
     229             :   }
     230             : 
     231             :   // Converting global deformations and deformation rates to the isolator
     232             :   // basic system.
     233       44424 :   _local_disp[_qp].reshape(12, 1);
     234       44424 :   _basic_disp[_qp].reshape(6, 1);
     235       44424 :   _basic_vel[_qp].reshape(6, 1);
     236       44424 :   _basic_disp_old[_qp].reshape(6, 1);
     237       44424 :   _basic_vel_old[_qp].reshape(6, 1);
     238             : 
     239       44424 :   _local_disp[_qp] = _total_gl[_qp] * global_disp;
     240       44424 :   _basic_disp[_qp] = _total_lb[_qp] * _total_gl[_qp] * global_disp;
     241       44424 :   _basic_vel[_qp] = _total_lb[_qp] * _total_gl[_qp] * global_vel;
     242       44424 :   _basic_disp_old[_qp] = _total_lb[_qp] * _total_gl[_qp] * global_disp_old;
     243       88848 :   _basic_vel_old[_qp] = _total_lb[_qp] * _total_gl[_qp] * global_vel_old;
     244       44424 : }

Generated by: LCOV version 1.14