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

Generated by: LCOV version 1.14