LCOV - code coverage report
Current view: top level - src/userobjects - ComputeExternalGrainForceAndTorque.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #32971 (54bef8) with base c6cf66 Lines: 112 131 85.5 %
Date: 2026-05-29 20:38:39 Functions: 11 11 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 "ComputeExternalGrainForceAndTorque.h"
      11             : #include "GrainTrackerInterface.h"
      12             : 
      13             : #include "libmesh/quadrature.h"
      14             : 
      15             : registerMooseObject("PhaseFieldApp", ComputeExternalGrainForceAndTorque);
      16             : 
      17             : InputParameters
      18          41 : ComputeExternalGrainForceAndTorque::validParams()
      19             : {
      20          41 :   InputParameters params = ShapeElementUserObject::validParams();
      21          41 :   params.addClassDescription("Userobject for calculating force and torque acting on a grain");
      22          82 :   params.addParam<MaterialPropertyName>("force_density", "force_density", "Force density material");
      23          82 :   params.addParam<UserObjectName>("grain_data", "center of mass of grains");
      24          82 :   params.addCoupledVar("c", "Concentration field");
      25          82 :   params.addCoupledVar("etas", "Array of coupled order parameters");
      26          41 :   return params;
      27           0 : }
      28             : 
      29          22 : ComputeExternalGrainForceAndTorque::ComputeExternalGrainForceAndTorque(
      30          22 :     const InputParameters & parameters)
      31             :   : DerivativeMaterialInterface<ShapeElementUserObject>(parameters),
      32             :     GrainForceAndTorqueInterface(),
      33          22 :     _c_name(coupledName("c", 0)),
      34          22 :     _c_var(coupled("c")),
      35          22 :     _dF_name(getParam<MaterialPropertyName>("force_density")),
      36          22 :     _dF(getMaterialPropertyByName<std::vector<RealGradient>>(_dF_name)),
      37          22 :     _dFdc(getMaterialPropertyByName<std::vector<RealGradient>>(
      38          22 :         derivativePropertyNameFirst(_dF_name, _c_name))),
      39          22 :     _op_num(coupledComponents("etas")),
      40          22 :     _grain_tracker(getUserObject<GrainTrackerInterface>("grain_data")),
      41          22 :     _vals_var(_op_num),
      42          22 :     _vals_name(_op_num),
      43          44 :     _dFdeta(_op_num)
      44             : {
      45          80 :   for (unsigned int i = 0; i < _op_num; ++i)
      46             :   {
      47          58 :     _vals_var[i] = coupled("etas", i);
      48         116 :     _vals_name[i] = coupledName("etas", i);
      49          58 :     _dFdeta[i] = &getMaterialPropertyByName<std::vector<RealGradient>>(
      50         116 :         derivativePropertyNameFirst(_dF_name, _vals_name[i]));
      51             :   }
      52          22 : }
      53             : 
      54             : void
      55         136 : ComputeExternalGrainForceAndTorque::initialize()
      56             : {
      57         136 :   _grain_num = _grain_tracker.getTotalFeatureCount();
      58         136 :   _ncomp = 6 * _grain_num;
      59             : 
      60         136 :   _force_values.resize(_grain_num);
      61         136 :   _torque_values.resize(_grain_num);
      62         136 :   _force_torque_store.assign(_ncomp, 0.0);
      63             : 
      64         136 :   if (_fe_problem.currentlyComputingJacobian())
      65             :   {
      66          32 :     _total_dofs = _subproblem.es().n_dofs();
      67          32 :     _force_torque_c_jacobian_store.assign(_ncomp * _total_dofs, 0.0);
      68          32 :     _force_torque_eta_jacobian_store.resize(_op_num);
      69             : 
      70          96 :     for (unsigned int i = 0; i < _op_num; ++i)
      71          64 :       _force_torque_eta_jacobian_store[i].assign(_ncomp * _total_dofs, 0.0);
      72             :   }
      73         136 : }
      74             : 
      75             : void
      76       25500 : ComputeExternalGrainForceAndTorque::execute()
      77             : {
      78       25500 :   const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
      79             : 
      80       76500 :   for (unsigned int i = 0; i < _grain_num; ++i)
      81      153000 :     for (unsigned int j = 0; j < _op_num; ++j)
      82      102000 :       if (i == op_to_grains[j])
      83             :       {
      84       17544 :         const auto centroid = _grain_tracker.getGrainCentroid(i);
      85       87720 :         for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
      86       70176 :           if (_dF[_qp][j](0) != 0.0 || _dF[_qp][j](1) != 0.0 || _dF[_qp][j](2) != 0.0)
      87             :           {
      88             :             const RealGradient compute_torque =
      89       70176 :                 _JxW[_qp] * _coord[_qp] *
      90       70176 :                 (_current_elem->vertex_average() - centroid).cross(_dF[_qp][j]);
      91       70176 :             _force_torque_store[6 * i + 0] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](0);
      92       70176 :             _force_torque_store[6 * i + 1] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](1);
      93       70176 :             _force_torque_store[6 * i + 2] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](2);
      94       70176 :             _force_torque_store[6 * i + 3] += compute_torque(0);
      95       70176 :             _force_torque_store[6 * i + 4] += compute_torque(1);
      96       70176 :             _force_torque_store[6 * i + 5] += compute_torque(2);
      97             :           }
      98             :       }
      99       25500 : }
     100             : 
     101             : void
     102       24000 : ComputeExternalGrainForceAndTorque::executeJacobian(unsigned int jvar)
     103             : {
     104       24000 :   const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
     105             : 
     106       24000 :   if (jvar == _c_var)
     107       72000 :     for (unsigned int i = 0; i < _grain_num; ++i)
     108      144000 :       for (unsigned int j = 0; j < _op_num; ++j)
     109       96000 :         if (i == op_to_grains[j])
     110             :         {
     111       16512 :           const auto centroid = _grain_tracker.getGrainCentroid(i);
     112       82560 :           for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     113       66048 :             if (_dFdc[_qp][j](0) != 0.0 || _dFdc[_qp][j](1) != 0.0 || _dFdc[_qp][j](2) != 0.0)
     114             :             {
     115       66048 :               const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
     116             :               const RealGradient compute_torque_jacobian_c =
     117       66048 :                   factor * (_current_elem->vertex_average() - centroid).cross(_dFdc[_qp][j]);
     118       66048 :               _force_torque_c_jacobian_store[(6 * i + 0) * _total_dofs + _j_global] +=
     119       66048 :                   factor * _dFdc[_qp][j](0);
     120       66048 :               _force_torque_c_jacobian_store[(6 * i + 1) * _total_dofs + _j_global] +=
     121       66048 :                   factor * _dFdc[_qp][j](1);
     122       66048 :               _force_torque_c_jacobian_store[(6 * i + 2) * _total_dofs + _j_global] +=
     123       66048 :                   factor * _dFdc[_qp][j](2);
     124       66048 :               _force_torque_c_jacobian_store[(6 * i + 3) * _total_dofs + _j_global] +=
     125             :                   compute_torque_jacobian_c(0);
     126       66048 :               _force_torque_c_jacobian_store[(6 * i + 4) * _total_dofs + _j_global] +=
     127             :                   compute_torque_jacobian_c(1);
     128       66048 :               _force_torque_c_jacobian_store[(6 * i + 5) * _total_dofs + _j_global] +=
     129             :                   compute_torque_jacobian_c(2);
     130             :             }
     131             :         }
     132             : 
     133       72000 :   for (unsigned int i = 0; i < _op_num; ++i)
     134       48000 :     if (jvar == _vals_var[i])
     135           0 :       for (unsigned int j = 0; j < _grain_num; ++j)
     136           0 :         for (unsigned int k = 0; k < _op_num; ++k)
     137           0 :           if (j == op_to_grains[k])
     138             :           {
     139           0 :             const auto centroid = _grain_tracker.getGrainCentroid(j);
     140           0 :             for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     141           0 :               if ((*_dFdeta[i])[_qp][j](0) != 0.0 || (*_dFdeta[i])[_qp][j](1) != 0.0 ||
     142           0 :                   (*_dFdeta[i])[_qp][j](2) != 0.0)
     143             :               {
     144           0 :                 const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
     145             :                 const RealGradient compute_torque_jacobian_eta =
     146             :                     factor *
     147           0 :                     (_current_elem->vertex_average() - centroid).cross((*_dFdeta[i])[_qp][k]);
     148           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 0) * _total_dofs + _j_global] +=
     149           0 :                     factor * (*_dFdeta[i])[_qp][k](0);
     150           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 1) * _total_dofs + _j_global] +=
     151           0 :                     factor * (*_dFdeta[i])[_qp][k](1);
     152           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 2) * _total_dofs + _j_global] +=
     153           0 :                     factor * (*_dFdeta[i])[_qp][k](2);
     154           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 3) * _total_dofs + _j_global] +=
     155             :                     compute_torque_jacobian_eta(0);
     156           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 4) * _total_dofs + _j_global] +=
     157             :                     compute_torque_jacobian_eta(1);
     158           0 :                 _force_torque_eta_jacobian_store[i][(6 * j + 5) * _total_dofs + _j_global] +=
     159             :                     compute_torque_jacobian_eta(2);
     160             :               }
     161             :           }
     162       24000 : }
     163             : 
     164             : void
     165         119 : ComputeExternalGrainForceAndTorque::finalize()
     166             : {
     167         119 :   gatherSum(_force_torque_store);
     168         357 :   for (unsigned int i = 0; i < _grain_num; ++i)
     169             :   {
     170         238 :     _force_values[i](0) = _force_torque_store[6 * i + 0];
     171         238 :     _force_values[i](1) = _force_torque_store[6 * i + 1];
     172         238 :     _force_values[i](2) = _force_torque_store[6 * i + 2];
     173         238 :     _torque_values[i](0) = _force_torque_store[6 * i + 3];
     174         238 :     _torque_values[i](1) = _force_torque_store[6 * i + 4];
     175         238 :     _torque_values[i](2) = _force_torque_store[6 * i + 5];
     176             :   }
     177             : 
     178         119 :   if (_fe_problem.currentlyComputingJacobian())
     179             :   {
     180          28 :     gatherSum(_force_torque_c_jacobian_store);
     181          84 :     for (unsigned int i = 0; i < _op_num; ++i)
     182          56 :       gatherSum(_force_torque_eta_jacobian_store[i]);
     183             :   }
     184         119 : }
     185             : 
     186             : void
     187          17 : ComputeExternalGrainForceAndTorque::threadJoin(const UserObject & y)
     188             : {
     189             :   const auto & pps = static_cast<const ComputeExternalGrainForceAndTorque &>(y);
     190         221 :   for (unsigned int i = 0; i < _ncomp; ++i)
     191         204 :     _force_torque_store[i] += pps._force_torque_store[i];
     192          17 :   if (_fe_problem.currentlyComputingJacobian())
     193             :   {
     194       68644 :     for (unsigned int i = 0; i < _ncomp * _total_dofs; ++i)
     195       68640 :       _force_torque_c_jacobian_store[i] += pps._force_torque_c_jacobian_store[i];
     196          12 :     for (unsigned int i = 0; i < _op_num; ++i)
     197      137288 :       for (unsigned int j = 0; j < _ncomp * _total_dofs; ++j)
     198      137280 :         _force_torque_eta_jacobian_store[i][j] += pps._force_torque_eta_jacobian_store[i][j];
     199             :   }
     200          17 : }
     201             : 
     202             : const std::vector<RealGradient> &
     203          69 : ComputeExternalGrainForceAndTorque::getForceValues() const
     204             : {
     205          69 :   return _force_values;
     206             : }
     207             : 
     208             : const std::vector<RealGradient> &
     209          69 : ComputeExternalGrainForceAndTorque::getTorqueValues() const
     210             : {
     211          69 :   return _torque_values;
     212             : }
     213             : 
     214             : const std::vector<Real> &
     215          50 : ComputeExternalGrainForceAndTorque::getForceCJacobians() const
     216             : {
     217          50 :   return _force_torque_c_jacobian_store;
     218             : }
     219             : const std::vector<std::vector<Real>> &
     220          50 : ComputeExternalGrainForceAndTorque::getForceEtaJacobians() const
     221             : {
     222          50 :   return _force_torque_eta_jacobian_store;
     223             : }

Generated by: LCOV version 1.14