LCOV - code coverage report
Current view: top level - src/userobjects - ComputeGrainForceAndTorque.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 128 129 99.2 %
Date: 2025-09-04 07:55:36 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          92 : ComputeGrainForceAndTorque::validParams()
      19             : {
      20          92 :   InputParameters params = ShapeElementUserObject::validParams();
      21          92 :   params.addClassDescription("Userobject for calculating force and torque acting on a grain");
      22         184 :   params.addParam<MaterialPropertyName>("force_density", "force_density", "Force density material");
      23         184 :   params.addParam<UserObjectName>("grain_data", "center of mass of grains");
      24         184 :   params.addCoupledVar("c", "Concentration field");
      25         184 :   params.addCoupledVar("etas", "Array of coupled order parameters");
      26          92 :   return params;
      27           0 : }
      28             : 
      29          48 : ComputeGrainForceAndTorque::ComputeGrainForceAndTorque(const InputParameters & parameters)
      30             :   : DerivativeMaterialInterface<ShapeElementUserObject>(parameters),
      31             :     GrainForceAndTorqueInterface(),
      32          48 :     _c_name(coupledName("c", 0)),
      33          48 :     _c_var(coupled("c")),
      34          48 :     _dF_name(getParam<MaterialPropertyName>("force_density")),
      35          48 :     _dF(getMaterialPropertyByName<std::vector<RealGradient>>(_dF_name)),
      36          48 :     _dFdc(getMaterialPropertyByName<std::vector<RealGradient>>(
      37          48 :         derivativePropertyNameFirst(_dF_name, _c_name))),
      38          48 :     _op_num(coupledComponents("etas")),
      39          48 :     _grain_tracker(getUserObject<GrainTrackerInterface>("grain_data")),
      40          48 :     _vals_var(_op_num),
      41          48 :     _vals_name(_op_num),
      42          96 :     _dFdgradeta(_op_num)
      43             : {
      44         144 :   for (unsigned int i = 0; i < _op_num; ++i)
      45             :   {
      46          96 :     _vals_var[i] = coupled("etas", i);
      47         192 :     _vals_name[i] = coupledName("etas", i);
      48          96 :     _dFdgradeta[i] = &getMaterialPropertyByName<std::vector<Real>>(
      49         192 :         derivativePropertyNameFirst(_dF_name, _vals_name[i]));
      50             :   }
      51          48 : }
      52             : 
      53             : void
      54         522 : ComputeGrainForceAndTorque::initialize()
      55             : {
      56         522 :   _grain_num = _grain_tracker.getTotalFeatureCount();
      57         522 :   _ncomp = 6 * _grain_num;
      58             : 
      59         522 :   _force_values.resize(_grain_num);
      60         522 :   _torque_values.resize(_grain_num);
      61         522 :   _force_torque_store.assign(_ncomp, 0.0);
      62             : 
      63         522 :   if (_fe_problem.currentlyComputingJacobian())
      64             :   {
      65         227 :     _total_dofs = _subproblem.es().n_dofs();
      66         227 :     _force_torque_c_jacobian_store.assign(_ncomp * _total_dofs, 0.0);
      67         227 :     _force_torque_eta_jacobian_store.resize(_op_num);
      68             : 
      69         681 :     for (unsigned int i = 0; i < _op_num; ++i)
      70         454 :       _force_torque_eta_jacobian_store[i].assign(_ncomp * _total_dofs, 0.0);
      71             :   }
      72         522 : }
      73             : 
      74             : void
      75       55765 : ComputeGrainForceAndTorque::execute()
      76             : {
      77       55765 :   const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
      78             : 
      79      164895 :   for (unsigned int i = 0; i < _grain_num; ++i)
      80      327390 :     for (unsigned int j = 0; j < _op_num; ++j)
      81      218260 :       if (i == op_to_grains[j])
      82             :       {
      83       32704 :         const auto centroid = _grain_tracker.getGrainCentroid(i);
      84      163520 :         for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
      85      130816 :           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        2345 :                 _JxW[_qp] * _coord[_qp] *
      89        2345 :                 (_current_elem->vertex_average() - centroid).cross(_dF[_qp][j]);
      90        2345 :             _force_torque_store[6 * i + 0] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](0);
      91        2345 :             _force_torque_store[6 * i + 1] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](1);
      92        2345 :             _force_torque_store[6 * i + 2] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](2);
      93        2345 :             _force_torque_store[6 * i + 3] += compute_torque(0);
      94        2345 :             _force_torque_store[6 * i + 4] += compute_torque(1);
      95        2345 :             _force_torque_store[6 * i + 5] += compute_torque(2);
      96             :           }
      97             :       }
      98       55765 : }
      99             : 
     100             : void
     101      287940 : ComputeGrainForceAndTorque::executeJacobian(unsigned int jvar)
     102             : {
     103      287940 :   const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
     104             : 
     105      287940 :   if (jvar == _c_var)
     106      292620 :     for (unsigned int i = 0; i < _grain_num; ++i)
     107      585240 :       for (unsigned int j = 0; j < _op_num; ++j)
     108      390160 :         if (i == op_to_grains[j])
     109             :         {
     110       58440 :           const auto centroid = _grain_tracker.getGrainCentroid(i);
     111      292200 :           for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     112      233760 :             if (_dFdc[_qp][j](0) != 0.0 || _dFdc[_qp][j](1) != 0.0 || _dFdc[_qp][j](2) != 0.0)
     113             :             {
     114        4228 :               const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
     115             :               const RealGradient compute_torque_jacobian_c =
     116        4228 :                   factor * (_current_elem->vertex_average() - centroid).cross(_dFdc[_qp][j]);
     117        4228 :               _force_torque_c_jacobian_store[(6 * i + 0) * _total_dofs + _j_global] +=
     118        4228 :                   factor * _dFdc[_qp][j](0);
     119        4228 :               _force_torque_c_jacobian_store[(6 * i + 1) * _total_dofs + _j_global] +=
     120        4228 :                   factor * _dFdc[_qp][j](1);
     121        4228 :               _force_torque_c_jacobian_store[(6 * i + 2) * _total_dofs + _j_global] +=
     122        4228 :                   factor * _dFdc[_qp][j](2);
     123        4228 :               _force_torque_c_jacobian_store[(6 * i + 3) * _total_dofs + _j_global] +=
     124             :                   compute_torque_jacobian_c(0);
     125        4228 :               _force_torque_c_jacobian_store[(6 * i + 4) * _total_dofs + _j_global] +=
     126             :                   compute_torque_jacobian_c(1);
     127        4228 :               _force_torque_c_jacobian_store[(6 * i + 5) * _total_dofs + _j_global] +=
     128             :                   compute_torque_jacobian_c(2);
     129             :             }
     130             :         }
     131             : 
     132      863820 :   for (unsigned int i = 0; i < _op_num; ++i)
     133      575880 :     if (jvar == _vals_var[i])
     134      571200 :       for (unsigned int j = 0; j < _grain_num; ++j)
     135     1142400 :         for (unsigned int k = 0; k < _op_num; ++k)
     136      761600 :           if (j == op_to_grains[k])
     137             :           {
     138      111888 :             const auto centroid = _grain_tracker.getGrainCentroid(j);
     139      559440 :             for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     140      447552 :               if ((*_dFdgradeta[i])[_qp][j] != 0.0)
     141             :               {
     142        8456 :                 const Real factor = _JxW[_qp] * _coord[_qp] * (*_dFdgradeta[i])[_qp][k];
     143             :                 const RealGradient compute_torque_jacobian_eta =
     144        8456 :                     factor * (_current_elem->vertex_average() - centroid).cross(_grad_phi[_j][_qp]);
     145        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 0) * _total_dofs + _j_global] +=
     146        8456 :                     factor * _grad_phi[_j][_qp](0);
     147        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 1) * _total_dofs + _j_global] +=
     148        8456 :                     factor * _grad_phi[_j][_qp](1);
     149        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 2) * _total_dofs + _j_global] +=
     150        8456 :                     factor * _grad_phi[_j][_qp](2);
     151        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 3) * _total_dofs + _j_global] +=
     152             :                     compute_torque_jacobian_eta(0);
     153        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 4) * _total_dofs + _j_global] +=
     154             :                     compute_torque_jacobian_eta(1);
     155        8456 :                 _force_torque_eta_jacobian_store[i][(6 * j + 5) * _total_dofs + _j_global] +=
     156             :                     compute_torque_jacobian_eta(2);
     157             :               }
     158             :           }
     159      287940 : }
     160             : 
     161             : void
     162         469 : ComputeGrainForceAndTorque::finalize()
     163             : {
     164         469 :   gatherSum(_force_torque_store);
     165        1391 :   for (unsigned int i = 0; i < _grain_num; ++i)
     166             :   {
     167         922 :     _force_values[i](0) = _force_torque_store[6 * i + 0];
     168         922 :     _force_values[i](1) = _force_torque_store[6 * i + 1];
     169         922 :     _force_values[i](2) = _force_torque_store[6 * i + 2];
     170         922 :     _torque_values[i](0) = _force_torque_store[6 * i + 3];
     171         922 :     _torque_values[i](1) = _force_torque_store[6 * i + 4];
     172         922 :     _torque_values[i](2) = _force_torque_store[6 * i + 5];
     173             :   }
     174             : 
     175         469 :   if (_fe_problem.currentlyComputingJacobian())
     176             :   {
     177         204 :     gatherSum(_force_torque_c_jacobian_store);
     178         612 :     for (unsigned int i = 0; i < _op_num; ++i)
     179         408 :       gatherSum(_force_torque_eta_jacobian_store[i]);
     180             :   }
     181         469 : }
     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         414 : ComputeGrainForceAndTorque::getForceValues() const
     201             : {
     202         414 :   return _force_values;
     203             : }
     204             : 
     205             : const std::vector<RealGradient> &
     206         414 : ComputeGrainForceAndTorque::getTorqueValues() const
     207             : {
     208         414 :   return _torque_values;
     209             : }
     210             : 
     211             : const std::vector<Real> &
     212      110268 : ComputeGrainForceAndTorque::getForceCJacobians() const
     213             : {
     214      110268 :   return _force_torque_c_jacobian_store;
     215             : }
     216             : const std::vector<std::vector<Real>> &
     217      220428 : ComputeGrainForceAndTorque::getForceEtaJacobians() const
     218             : {
     219      220428 :   return _force_torque_eta_jacobian_store;
     220             : }

Generated by: LCOV version 1.14